проверка соединения c3p0 занимает 15 минут, чтобы иногда потерпеть неудачу
Поразите проблему, используя c3p0. В большинстве случаев работает нормально,но в prod env за брандмауэрами ocasionally не удается проверить соединение. Проблема в том, что требуется 15 минут, чтобы распознать, что соединение не используется. Пул не exausted, поскольку другие соединения проверяются и используются счастливо в течение этого 15-минутного inteval.
Журналы:
23 Apr 2015 09:08:16.426 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282] on CHECKOUT.
15 минут спустя:
23 Apr 2015 09:23:43.073 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282] on CHECKOUT has FAILED.
java.sql.SQLException: Connection is invalid
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:572) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.finerLoggingTestPooledConnection(C3P0PooledConnectionPool.java:451) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.finerLoggingTestPooledConnection(C3P0PooledConnectionPool.java:443) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishResourceOnCheckout(C3P0PooledConnectionPool.java:336) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.resourcepool.BasicResourcePool.attemptRefurbishResourceOnCheckout(BasicResourcePool.java:1727) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:553) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:756) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:683) [c3p0-0.9.5.jar:0.9.5]
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140) [c3p0-0.9.5.jar:0.9.5]
И затем еще несколько журналов:
23 Apr 2015 09:23:43.073 [EventProcessor-1] DEBUG c.m.v.r.BasicResourcePool - A resource could not be refurbished for checkout. [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282]
java.sql.SQLException: Connection is invalid
...
23 Apr 2015 09:23:43.074 [EventProcessor-1] DEBUG c.m.v.r.BasicResourcePool - Resource [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282] could not be refurbished in preparation for checkout. Will try to find a better resource.
23 Apr 2015 09:23:43.074 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.r.BasicResourcePool - Preparing to destroy resource: com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282
23 Apr 2015 09:23:43.074 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@41318736] on CHECKOUT.
23 Apr 2015 09:23:43.074 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Preparing to destroy PooledConnection: com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282
23 Apr 2015 09:23:43.076 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.c3p0.impl.NewPooledConnection - Failed to close physical Connection: oracle.jdbc.driver.T4CConnection@25145762
java.sql.SQLRecoverableException: IO Error: Broken pipe
at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:612) ~[ojdbc6_g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:5094) ~[ojdbc6_g-11.2.0.1.0.jar:11.2.0.1.0]
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:642) [c3p0-0.9.5.jar:0.9.5]
Конфигурация C3p0:
ComboPooledDataSource ods = new ComboPooledDataSource();
...
ods.setInitialPoolSize(5);
ods.setMinPoolSize(5);
ods.setMaxPoolSize(10);
ods.setMaxStatements(50);
ods.setTestConnectionOnCheckout(true);
Так что ничего слишком экзотично. Я знаю, что возможна потеря соединения, поэтому тестирую соединение при проверке. Есть идеи, почему проверка / сбой соединения занимает так много времени? Мы используем базу данных Oracle.
спасибо.
2 ответов:
Во-первых, я предполагаю, что вы проверили, что нет никаких проверок этой связи между вашими сообщениями журнала. Очевидно, вы ожидали бы много сообщений, как...
Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282] on CHECKOUT....перед окончательным сообщением, непосредственно перед неудачей. Многие из этих сообщений появлялись гораздо раньше. Только последнее сообщение непосредственно перед сбоем должно, в идеале, быть гораздо ближе к обнаружению сбоя, чем те 15 минут, которые вы видите.
Если предположить, что это последнее сообщение, то проблема связана с тем, как умирают ваши связи. c3p0 выполняет тест, а затем ожидает либо успешного завершения, либо исключения. Если ваше соединение умирает таким образом, что тест соединения просто висит в течение 15 минут, что ж, тогда вы можете увидеть то, что видите.
Вот несколько предложений.В любом случае, я надеюсь, что это не совсем бесполезно!
- используйте c3p0 idleConnectionTestPeriod для обнаружения этих сбоев в идеале до проверки клиента, так что клиенты с меньшей вероятностью будут испытывать длительные зависания. (Вы можно было бы проверить и при регистрации.)
- выясните, какой тест соединения выполняется. Вы используете c3p0 0.9.5, поэтому, если ваш драйвер поддерживает его, тест по умолчанию-это вызов соединения.isValid (), который должен быть быстрым. Я не вижу ни в одном из журналов, которые вы процитировали, трассировки стека фактического провала теста (возможно, это усеченное исключение корневой причины? Это определенно будет записано на более тонком / отладочном уровне регистратором под названием
com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool) Проверьте (из трассировки стека), что ваш драйвер использует быстрыйisValid()Тест соединения, а не медленный тест соединения по умолчанию c3p0. Если это не так (предположительно, потому что ваш драйвер не поддерживает это), то рассмотрите возможность установки быстрогоpreferredTestQuery.- Вы можете попробовать maxAdministrativeTaskTime , но это, скорее всего, действительно поможет, если то, что висит тест соединения, отвечает на вызов interrupt ().
Похоже, что это ситуация, когда соединение прерывается брандмауэром таким образом, что ответ не отправляется вообще, даже TCP ACK без данных. В этом случае запрос на проверку соединения никогда не вернется. Это на уровне драйвера сокета/jdbc.
Решение:
- Узнайте политику отключения брандмауэра (в нашем случае 1 час)
- set c3p0.maxConnectionAge свойство для принудительного повторного подключения соединений c3p0 каждые X секунд.
Comments