проверка соединения 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.
спасибо.

538   2  

2 ответов:

Во-первых, я предполагаю, что вы проверили, что нет никаких проверок этой связи между вашими сообщениями журнала. Очевидно, вы ожидали бы много сообщений, как...

Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5a886282] on CHECKOUT.

...перед окончательным сообщением, непосредственно перед неудачей. Многие из этих сообщений появлялись гораздо раньше. Только последнее сообщение непосредственно перед сбоем должно, в идеале, быть гораздо ближе к обнаружению сбоя, чем те 15 минут, которые вы видите.

Если предположить, что это последнее сообщение, то проблема связана с тем, как умирают ваши связи. c3p0 выполняет тест, а затем ожидает либо успешного завершения, либо исключения. Если ваше соединение умирает таким образом, что тест соединения просто висит в течение 15 минут, что ж, тогда вы можете увидеть то, что видите.

Вот несколько предложений.
  1. используйте c3p0 idleConnectionTestPeriod для обнаружения этих сбоев в идеале до проверки клиента, так что клиенты с меньшей вероятностью будут испытывать длительные зависания. (Вы можно было бы проверить и при регистрации.)
  2. выясните, какой тест соединения выполняется. Вы используете c3p0 0.9.5, поэтому, если ваш драйвер поддерживает его, тест по умолчанию-это вызов соединения.isValid (), который должен быть быстрым. Я не вижу ни в одном из журналов, которые вы процитировали, трассировки стека фактического провала теста (возможно, это усеченное исключение корневой причины? Это определенно будет записано на более тонком / отладочном уровне регистратором под названием com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool) Проверьте (из трассировки стека), что ваш драйвер использует быстрый isValid() Тест соединения, а не медленный тест соединения по умолчанию c3p0. Если это не так (предположительно, потому что ваш драйвер не поддерживает это), то рассмотрите возможность установки быстрого preferredTestQuery.
  3. Вы можете попробовать maxAdministrativeTaskTime , но это, скорее всего, действительно поможет, если то, что висит тест соединения, отвечает на вызов interrupt ().
В любом случае, я надеюсь, что это не совсем бесполезно!

Похоже, что это ситуация, когда соединение прерывается брандмауэром таким образом, что ответ не отправляется вообще, даже TCP ACK без данных. В этом случае запрос на проверку соединения никогда не вернется. Это на уровне драйвера сокета/jdbc.

Решение:

  • Узнайте политику отключения брандмауэра (в нашем случае 1 час)
  • set c3p0.maxConnectionAge свойство для принудительного повторного подключения соединений c3p0 каждые X секунд.

Comments

    Ничего не найдено.