#oracle #c3p0 #mule-esb
Вопрос:
Я новичок в объединении баз данных Java и c3p0. У нас есть встроенный api на mulesoft и развернутый в cloudhub (конфигурация vpc vpn), приложение подключается к локальной базе данных.
В журналах приложений показано ниже предупреждение о закрытии соединения каждые 12 часов (ровно)
16:59:32.799 07/28/2021 Worker-0 C3P0PooledConnectionPoolManager[identityToken->|41d2c93]-HelperThread-#2 WARN
Statement close FAILED.
java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.PhysicalConnection.needLine(PhysicalConnection.java:3525)
at oracle.jdbc.driver.OracleStatement.closeOrCache(OracleStatement.java:1478)
at oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:1461)
at oracle.jdbc.driver.OracleStatementWrapper.close(OracleStatementWrapper.java:122)
at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:53)
at com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:325)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:510)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:464)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:436)
at com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:2211)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Если запрос получен в течение последних нескольких минут, достигающих 12 часов, то он завершается с ошибкой 500 connection.ConnectionException: An attempt by a client to checkout a Connection has timed out
Я настроил источник данных на основе spring, и вот моя конфигурация
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<bean id="oracle-jdbcdatasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@${oracle.host}:${oracle.port}/${oracle.database}"/>
<property name="user" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="5"/>
<property name="initialPoolSize" value="1"/>
<property name="acquireIncrement" value="1"/>
<property name="idleConnectionTestPeriod" value="300"/>
<property name="maxStatements" value="0"/>
<property name="checkoutTimeout" value="60000"/>
<property name="testConnectionOnCheckout" value="true" />
<property name="testConnectionOnCheckin" value="true" />
<property name="preferredTestQuery" value="select 1 from dual" />
<property name="maxConnectionAge" value="14400" />
<property name="maxIdleTime" value="7200" />
</bean>
</beans>
Я установил maxConnectionAge
значение 14400 (4 часа) и maxIdleTime
7200 (2 часа), поэтому я не ожидал увидеть ошибку закрытия соединения, так как она должна была разрушить соединение до 12 часов, и новое соединение должно быть установлено.
Подробная информация о версии
- Время выполнения мула — 4.3.0
- Oracle jdbc8 — 19.3.0.0
- c3p0 — 0.9.5.2
Может ли кто-нибудь, пожалуйста, сообщить, не отсутствует ли у меня какая-либо конфигурация для объединения c3p0 ?
Спасибо
Ответ №1:
Я не думаю, что в конфигурации пула что-то не так. Это может быть проблема с повторным подключением в VPN или даже какое-то ограничение в самой базе данных.
Комментарии:
1. Привет, Алед, спасибо за быстрый ответ. Есть ли способ отладить эту проблему, включив журналы для c3p0, чтобы видеть, что происходит ? Есть ли какая-либо конфигурация, которую мне нужно включить для повторного подключения на соединителе базы данных c3p0 или mule ?
2. Я так не думаю. Таковы конфигурации, и Мул просто использует компонент источника данных в качестве черного ящика. C3p0 реализует пул. Включение ведения журнала c3p0 может дать вам некоторые сообщения, но не уверен, что это полезно для устранения неполадок. Если проблема в инфраструктуре (например, VPN), вы ничего не увидите в приложении.
3. Как я могу включить журналы отладки для c3p0? Я подозревал, что maxConnectionAge и maxIdleTime не работают или конфликтуют с другим свойством, так как оно должно удалять соединение через 4 часа, но, похоже, соединение все еще работает дольше, и vpn или база данных закрывают его.
4. Вы уверены, что используете все запросы? Это должно закрыть все связи. Например, используя a для каждой области после каждого запроса, чтобы убедиться, что все результаты будут использованы. В противном случае соединения могут быть все еще открыты.
5. Я добавил журналы отладки, и ошибка возникает, когда c3p0 проверяет соединение каждые 5 минут.
DEBUG - Connection oracle.jdbc.driver.T4CConnection@62fd7c9 failed Connection test with an Exception! [query=select 1 from dual]
. Если тестовый запрос завершится неудачно, то реальный запрос к БД также завершится неудачно.
Ответ №2:
Похоже, что вы, возможно, проверяете соединения, но не сразу возвращаете их обратно. Срок действия старых соединений c3p0 не истечет, если они останутся проверенными, только после их регистрации.
Сообщение «Время ожидания попытки клиента проверить соединение истекло» указывает на то, что в конечном итоге вы исчерпали пул подключений, для проверки не осталось подключений, и maxPoolSize
оно было достигнуто.
Когда ваше приложение проверяет соединения, оно должно использовать конструкцию «Попробуйте с ресурсами«, чтобы обеспечить быструю проверку соединения после использования.
Комментарии:
1. Поскольку я использую соединитель базы данных мула, у меня нет возможности контролировать это, так что это может быть дефект на стороне мула.
2. Даже если соединение не возвращается, настройка maxConnectionAge должна вызвать c3p0 для его восстановления, согласно документации c3p0. И обратите внимание, что вопрос касается приложений Mule, использующих соединитель базы данных. попробуйте с ресурсами для приложений Java.
3. итак, я ничего не знаю о муле, но я немного знаю о c3p0. в документации c3p0 говорится
maxConnectionAge
, что соединение должно быть выбраковано или удалено из пула . он не сбрасывается при возврате клиента (какmaxIdleTime
это происходит), но он также не закрывает соединения под клиентскими приложениями, которые их уже проверили.4. единственная настройка c3p0, которая приведет к уничтожению подключений, проверенных и находящихся на хранении клиентов, — это
unreturnedConnectionTimeout
. поскольку проблема, по-видимому, заключается в том, что приложение проверяет и удерживает, а не быстро возвращает соединения, вы можете подумать о том, чтобы поэкспериментироватьunreturnedConnectionTimeout
иdebugUnreturnedConnectionStackTraces
лучше понять, что происходит.