Oracle JDB C: установить тайм-аут для «Указан неизвестный хост» - PullRequest
0 голосов
/ 14 июля 2020

Этот и подобные вопросы задавались много раз, но ни одна из рекомендуемых настроек у меня не работает.

Мне нужно настроить тайм-аут для случая, если хост БД недоступен или Oracle БД

Мне нужно проверить состояние сервера Oracle DB в Docker, поэтому я выполняю select 1 from dual в bash l oop, но DriverManager.getConnection возвращается (с указанным исключением) через 20 секунд, что для меня слишком много. Я хотел бы уменьшить этот тайм-аут до 1 сек. c.

Я знаю, что есть инструмент Oracle, называемый TNSPING, для проверки состояния Oracle сервера БД, но, к сожалению, этот инструмент не является частью официального образа Oracle DB, и я не хочу устанавливать какой-либо продукт Oracle в Docker только из-за TNSPING.

Это то, что я пробовал до сих пор, но используемые мной настройки не влияет на этот тайм-аут. Исключение java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection появляется через 20 секунд c. вместо 1 se c. Неважно, что я использую 1, 1000 или 10000 в коде java, тайм-аут всегда равен 20 сек c.

private Connection getConnection(String jdbcUrl) throws SQLException {
    String timeout = "100";
    Properties p = new Properties();
    p.put(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CONNECT_TIMEOUT, timeout);
    p.put(OracleConnection.CONNECTION_PROPERTY_THIN_READ_TIMEOUT, timeout);
    p.put(OracleConnection.CONNECTION_PROPERTY_THIN_JNDI_LDAP_CONNECT_TIMEOUT, timeout);
    p.put(OracleConnection.CONNECTION_PROPERTY_THIN_JNDI_LDAP_READ_TIMEOUT, timeout);
    p.put(OracleConnection.CONNECTION_PROPERTY_THIN_OUTBOUND_CONNECT_TIMEOUT, timeout);
    p.put(OracleConnection.CONNECTION_PROPERTY_DOWN_HOSTS_TIMEOUT, timeout);
    p.put("oracle.jdbc.ReadTimeout", timeout);
    p.put("oracle.net.CONNECT_TIMEOUT", timeout);

    p.put (OracleConnection.CONNECTION_PROPERTY_USER_NAME, user);
    p.put (OracleConnection.CONNECTION_PROPERTY_PASSWORD, password);

    System.setProperty("oracle.net.READ_TIMEOUT", timeout);
    System.setProperty("oracle.jdbc.ReadTimeout", timeout);
    System.setProperty("oracle.jdbc.javaNetNio", "true");

    DriverManager.setLoginTimeout(Integer.valueOf(timeout));
    Connection connection = DriverManager.getConnection(jdbcUrl, p);
    connection.setNetworkTimeout(Executors.newSingleThreadExecutor(), Integer.valueOf(timeout));

    return connection;
}

Я не хочу добавлять решение пула соединений в мой простой app, мне может хватить только чистого JDB C.

Что я тут упустил?

- ОБНОВЛЕНИЕ -

Вроде что проблема специфична для среды c и, возможно, не связана с Java, но все еще не уверен.

Если я выполняю точно такую ​​же команду на своем компьютере и в Docker, я получаю обратно общую сумму разное время выполнения:

команда:

$ time java -jar sql-runner-0.2.0-SNAPSHOT-with-dependencies.jar -j jdbc:oracle:thin:@//somehost:1521/somedb -U "doesnotmatter" -P "password" "select 1 from dual"

Результат в docker:

IO Error: Unknown host specified 

real    0m20.521s
user    0m0.764s
sys 0m0.097s

Результат, если я выполню его на своем компьютере:

IO Error: Unknown host specified 

real    0m0.501s
user    0m0.715s
sys 0m0.095s

Полный исходный код доступен здесь .

Такое странное поведение.

1 Ответ

0 голосов
/ 15 июля 2020

Могут быть разные причины, по которым это не работает для вас:

  • в зависимости от JDB C время ожидания версии драйверов может составлять миллисекунды или секунды
  • некоторые параметры, которые вы устанавливаете, просто игнорируется версией вашего драйвера
  • , могут быть различные проблемы с DNS, например, Oracle прослушиватель SCAN отправляет вам перенаправление на узел кластера RA C. И ваш клиент не может разрешить это имя хоста.

У вас есть следующие варианты диагностики вашей проблемы:

strace:

strace -f -e trace=network -o strace.log java -jar sql-runner-0.2.0-SNAPSHOT-with-dependencies.jar -j jdbc:oracle:thin:@//somehost:1521/somedb -U "doesnotmatter" -P "password" "select 1 from dual"

JDB с включенной отладкой C драйвер (* _g.jar):

$ java -Doracle.jdbc.Trace=true \ 
-Djava.util.logging.config.file=Logging.properties \
-classpath "ojdbc8_g.jar:..." \
...

$ cat Logging.properties
.level=OFF

#.level=SEVERE
handlers=java.util.logging.FileHandler

#  example of a full pathname in Windows
java.util.logging.FileHandler.pattern=Networkpacket.log

# Predefined levels are: ALL, SEVERE, WARNING, INFO, CONFIG, FINE, FINER,
#                        FINEST, OFF

java.util.logging.FileHandler.limit = 500000000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.level =ALL
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
oracle.net.ns.level = ALL

## Following levels are commented to filter the network packet contents.

#oracle.jdbc.level=oFF
#oracle.jdbc.aq.level=OFF
#oracle.jdbc.driver.level=OFF
#oracle.jdbc.pool.level=OFF
#oracle.jdbc.rowset.level=OFF
#oracle.jdbc.xa.level=OFF
#oracle.sql.level=OFF
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...