Tomcat игнорирует removeAbandonedTimeout и закрывает соединения в пуле

Я работаю над Tomcat 7.0 с JDBC-соединением с DB2 на as400 с использованием dbcp в общем достоянии. Как только я загружаю сервер, он сразу же открывает и закрывает соединения с базой данных, игнорируя установленный мной 30-минутный параметр removeAbandonedTimeout. Я пробовал несколько настроек безрезультатно. Например, через 15 секунд он откроет 150 соединений и закроет 140 без видимой причины. У нас есть приложение, работающее на старом сервере WebSphere, и оно не закрывает соединения, если они действительно не работают.

Вот моя конфигурация:

 <Resource name="MYDB"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
          driverClassName="com.ibm.as400.access.AS400JDBCDriver"
          url="jdbc:as400://mydb.na.sysco.net;blockCriteria=2;dateFormat=iso;libraries=*LIBL;naming=system;errors=full"
          username="user"
          password="pass"
          maxActive="350"
          maxWait="180000"
          minIdle="10"
          maxIdle="50"
          testWhileIdle="true"
          validationQuery="select 1 from sysibm.sysdummy1"
          timeBetweenEvictionRunsMillis="34000"
          minEvictableIdleTimeMillis="1800000"
          removeAbandonedTimeout="1800"
          removeAbandoned="true"
          logAbandoned="true"/>

Когда система находится в режиме ожидания или только несколько тестовых учетных записей, она ведет себя, как и ожидалось, но как только я загружаю сервер, массовые открытия и закрытия запускаются немедленно. Например, он откроет 150 соединений и закроет 90 соединений за тот же 15-секундный интервал. Я читаю, что сокеты открываются и закрываются, что соответствует началу и окончанию заданий QZ на as400 из моего программного обеспечения для мониторинга. Он будет постоянно делать это, пока используются соединения.

Это побеждает назначение пулов соединений. Любые мысли или идеи приветствуются.

Также сбивает с толку, потому что не ясно, какие параметры я должен использовать для начала. Параметры dbcp commons, которые являются уникальными из параметров пула соединений JDBC Tomcat, не принимаются, т. Е. RemoveAbandonedOnMaintenance. Но значение по умолчанию 1800000 для minEvictableIdleTimeMillis выбрано, а не 60000 из параметров пула Tomcat jdbc.

https://commons.apache.org/proper/commons-dbcp/api-1.2.2/index.html

https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

Когда я не устанавливаю параметры явно, это то, что я получаю по умолчанию. Похоже, в нем перечислены все параметры пула tomcat jdbc, а не параметры общего ресурса DBCP. Однако он выбирает значение по умолчанию для minEvictableIdleTimeout из общего ресурса DBCP, а не 60 секунд из параметров пула соединений Tomcat JDBC. Незнакомая часть - это параметр removeAbandoned, который не указан для dbcp общего ресурса, это - removeAbandonedOnMaintenance и removeAbandonedOnBorrow. Я пытаюсь прижать это желе к стене уже неделю.

Я использую jmxproxy для получения статистики и настроек в реальном времени.

http://myserver:8080/manager/jmxproxy/?qry=Catalina%3Atype%3DDataSource%2C*

Name: Catalina:type=DataSource,class=javax.sql.DataSource,name="EOPDB"
modelerType: org.apache.tomcat.util.modeler.BaseModelMBean
maxIdle: 8
testOnBorrow: false
defaultTransactionIsolation: -1
testOnReturn: false
maxActive: 350
numActive: 104
numTestsPerEvictionRun: 3
minIdle: 0
maxWait: 180000
closed: false
defaultAutoCommit: true
numIdle: 8
validationQueryTimeout: -1    
testWhileIdle: false
driverClassName: com.ibm.as400.access.AS400JDBCDriver
accessToUnderlyingConnectionAllowed: false
url: jdbc:as400://mydb;blockCriteria=2;dateFormat=iso;libraries=*LIBL;naming=system;errors=full
removeAbandonedTimeout: 300
defaultReadOnly: false
logAbandoned: false
poolPreparedStatements: false
maxOpenPreparedStatements: -1
removeAbandoned: false
minEvictableIdleTimeMillis: 1800000
timeBetweenEvictionRunsMillis: -1
initialSize: 0

2 ответа

Решение

maxIdle - максимальное количество соединений, которые могут оставаться незанятыми в пуле. Как только число незанятых соединений пересекает maxIdle, любое соединение, выпущенное приложением, немедленно закрывается без проверки времени простоя соединения для minEvictableIdleTimeMillis.

Есть 2 значения, которые могут быть потенциально проблематичными в вашем сценарии

      timeBetweenEvictionRunsMillis="34000"
      removeAbandoned="true"

timeBetweenEvictionRunsMillis
в вашем сценарии 34 секунды, 150 соединений были созданы в середине этого периода и 90 разорваны, когда пришло время, оставив 60 подключений в пуле, почти 50 из которых были запрошены maxIdle=50. Выглядит непропорционально по сравнению с minEvictableIdleTimeMillis, так как вы ожидаете, что простаивающее соединение будет жить 30 минут (1800000 мс) в пуле, но вы будете проверять каждые 34 секунды, не предпринимая никаких действий, потому что соединения должны жить намного дольше.

removeAbandonedTimeout Это заставляет ваше приложение выполнять запросы быстрее, чем за 1,8 секунды.

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

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

Варианты объяснены здесь.

Другие вопросы по тегам