Tomcat 7.0.47
MySQL连接器/ J 5.1.20

我正在测试HA数据库设置,其中可以通过DNS名称访问mysql DB(AWS中的RDS)。故障转移后,数据库将获得新的IP。

我有一个测试Web应用程序,具有在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"
/>


如您所见,定义的连接数量很少,因此可以更轻松地重现此问题。我有一个Web客户端,它每秒进行一次AJAX REST调用,此调用只对DB进行一次选择和一次插入。 Web框架是使用Spring JDBC的Spring MVC。

我启动了足够多的客户端以最大化并发数据库的使用率,然后对数据库进行故障转移。数据库恢复并且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知道这些连接已死并将它们从池中弹出吗?我相信这是removeAbandoned =“ true”的意图,但在这里似乎无济于事。

有任何想法吗?

-更新-

在调试器中,我发现清理废弃连接的PoolCleaner线程挂在JDBC4Connection(ConnectionImpl).close():1641上。 PoolCleaner停止并且连接没有得到清理。不知道为什么close()超时...

最佳答案

您可能会遇到JDBC连接泄漏问题,其中客户端没有再见就走了,服务器端认为连接很忙,因此永远不要将繁忙的连接回收到池中。

关于mysql - Tomcat 7 JDBC池在故障转移期间耗尽,无法恢复,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22461229/

10-12 00:36
查看更多