Пул Tomcat 7 JDBC исчерпан во время отработки отказа и не восстанавливается

Tomcat 7.0.47 Коннектор MySQL / J 5.1.20

Я тестирую настройку базы данных высокой доступности, где база данных mysql (RDS в AWS) доступна по имени DNS. После отработки отказа БД получит новый IP.

У меня есть тестовое веб-приложение со следующим подключением к базе данных, определенным в context.xml:

<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"
  maxActive="3" maxIdle="2" maxWait="1000" name="jdbc/db"
  password=“xxx” type="javax.sql.DataSource"
  url="jdbc:mysql://xxx:3306/xxx?autoReconnect=true" username="root"
  factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
  removeAbandoned="true" logAbandoned="true" removeAbandonedTimeout="60"
/>

Как видите, определено очень небольшое количество подключений, поэтому эту проблему легче воспроизвести. У меня есть веб-клиент, который каждую секунду выполняет вызов AJAX REST, этот вызов просто делает один выбор и одну вставку в БД. Веб-фреймворк - это Spring MVC с использованием Spring JDBC.

Я раскручиваю достаточно клиентов, чтобы максимально увеличить одновременное использование БД, а затем перехожу к базе данных. база данных восстанавливается, и DNS переключается на новый IP. Поведение, которое я наблюдаю в Tomcat, заключается в том, что соединения никогда не освобождаются и не прекращаются.

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/test] threw exception [Request processing failed; nested exception
  is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; 
  nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-bio-8080-exec-11] Timeout: Pool empty. Unable to fetch a connection in 1 seconds, none available[size:3; busy:2; idle:0; lastwait:1000].] with root cause
  org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-bio-8080-exec-11] Timeout: Pool empty. Unable to fetch a connection in 1 seconds, none available[size:3; busy:2; idle:0; lastwait:1000].
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:674)

... и приложение никогда не восстанавливается. Я ищу способ для Tomcat восстановить эти соединения без перезапуска Tomcat. Конечно, Tomcat должен быть далеко, чтобы распознать, что эти соединения мертвы, и выбросить их из пула? Я считаю, что это намерение removeAbandoned = "true", но, похоже, здесь это не помогает.

Любые идеи?

--- ОБНОВИТЬ ---

В отладчике я обнаружил, что поток PoolCleaner, который очищает брошенные соединения, зависает от JDBC4Connection (ConnectionImpl) .close (): 1641. PoolCleaner остановлен, и соединения не очищаются. Не уверен, почему close () истекает время ожидания ...


person Chris Moyer    schedule 17.03.2014    source источник
comment
Посмотрите раздел «Проверка подключений» на сайте tomcatexpert.com / blog / 2010/04/01 /, может быть, вам поможет.   -  person vzamanillo    schedule 17.03.2014
comment
Я добавил следующее ... testOnBorrow = true validationQuery = SELECT 1 timeBetweenEvictionRunsMillis = 10000 minEvictableIdleTimeMillis = 60000 validationInterval = 30000 ... Без эффекта. Кажется, пул думает, что каждое соединение занято.   -  person Chris Moyer    schedule 17.03.2014
comment
Попробуйте добавить org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer в jdbcInterceptors, посмотрите tomcat.apache.org/tomcat-7.0-doc/   -  person vzamanillo    schedule 17.03.2014
comment
Добавил, спасибо за идею. К сожалению, никакого эффекта. Похоже, что все 3 соединения заняты? ResetAbandonedTimer выглядит так, как будто он увеличивает время, по истечении которого соединение считается разорванным. Странно, похоже, что эти соединения вообще не обнаруживаются детектором брошенных соединений.   -  person Chris Moyer    schedule 17.03.2014
comment
Удалось ли вам решить эту проблему? Я сталкиваюсь с тем же.   -  person Bee    schedule 06.05.2014
comment
Нет разрешения. Лучшее, что мы придумали на данный момент, - это попытаться обнаружить серверы приложений в этом состоянии и убить их. Мы все еще ищем решение.   -  person Chris Moyer    schedule 07.05.2014


Ответы (1)


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

person Jimmy Chen    schedule 17.07.2016