Tomcat 忽略 removeAbandonedTimeout 并关闭池中的连接

Tomcat ignores removeAbandonedTimeout and closes connections in pool

我正在开发 tomcat 7.0,在 as400 上使用 commons dbcp JDBC 连接到 DB2。一旦我在服务器上加载负载,它就会立即打开和关闭与数据库的连接,而忽略我设置的 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"/>

当系统空闲或只有几个测试帐户时,它的行为符合预期,但一旦我在服务器上加载负载,大量的打开和关闭立即开始。例如,它将在相同的 15 秒间隔内打开 150 个连接并关闭 90 个连接。我正在从我的监控软件中读取与 as400 上 QZ 作业的开始和结束相关的套接字打开和关闭。它会在使用连接时不断地这样做。

这违背了连接池的目的。任何想法或想法都会受到赞赏。

同样令人困惑,因为不清楚我应该使用哪些参数开始。 Tomcat JDBC 连接池参数中唯一的公共 dbcp 参数未被接受,即 removeAbandonedOnMaintenance。但是 minEvictableIdleTimeMillis 的默认值 1800000 是从 Tomcat jdbc 池参数中获取的,而不是 60000。

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 参数。但是,它从公共 DBCP 中获取 minEvictableIdleTimeout 的默认值,而不是从 Tomcat JDBC 连接池参数中获取 60 秒。奇怪的部分是 removeAbandoned 参数没有为 commons 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 个值在您的场景中可能存在问题

      timeBetweenEvictionRunsMillis="34000"
      removeAbandoned="true"

timeBetweenEvictionRunsMillis
是 34 秒,在您的场景中,在此期间中间创建了 150 个连接,当时间到来时,90 个连接被销毁,在池中留下 60 个连接,几乎是 maxIdle=50 请求的 50 个连接。与 minEvictableIdleTimeMillis 相比看起来不成比例,因为您希望空闲连接在池中存活 30 分钟(1800000 毫秒),但您每 34 秒检查一次而不采取任何操作,因为连接应该存活更长时间。

删除放弃超时 它迫使您的应用程序 运行 查询速度快于 1.8 秒。

The value should be set to the longest running query your applications might have.

确保您的应用程序正确地将连接返回到池中,它们将被视为已放弃和关闭。
希望这有帮助。

选项是explained here

maxIdle 是池中可以保持空闲的最大连接数。一旦空闲连接数超过 maxIdle,应用程序释放的任何连接都会立即关闭,而不根据 minEvictableIdleTimeMillis 检查连接空闲时间。