Tomcat JDBC 池连接全部卡在 Socket Read 上,没有创建新连接

Posted

技术标签:

【中文标题】Tomcat JDBC 池连接全部卡在 Socket Read 上,没有创建新连接【英文标题】:Tomcat JDBC pool connections all stuck at Socket Read, and no new connection is created 【发布时间】:2013-03-10 07:30:50 【问题描述】:

我有一个托管在 Amazon ElasticBeanstalk 上的 Tomcat 7 应用程序,以及一个托管在 Amazon RDS 上的 mysql 5.5 数据库。数据库服务器仅服务于一个 Tomcat 应用程序,并且最大连接限制设置为 10,000。

然而,在运行了几个小时后,数据库连接发生了奇怪的事情。

MySQL 服务器报告 Tomcat JDBC 连接池只创建了 3 个连接,它们都在“休眠”(示例输出):

| 228 | root     | ip-10-240-xx-xxx.ap-southeast-2.compute.internal:33270 | xxxxx | Sleep   |   13 |       | NULL             |

Tomcat 线程转储提示所有 3 个连接都在从网络 IO 套接字读取(阻塞):

at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:150)
        at java.net.SocketInputStream.read(SocketInputStream.java:121)
        at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
        at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
        at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
        - locked <0x00000000bc349cc0> (a com.mysql.jdbc.util.ReadAheadInputStream)
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3036)

由于连接池中只有 3 个 DB 连接,并且它们都卡在 IO 读取上,因此 Tomcat 拒绝服务任何需要 DB 数据的 HTTP 请求。

已分配 Tomcat JDBC 池设置:

maxActive="500"
maxIdle="100"
minIdle="50"
initialSize="50"
maxWait="15000"
timeBetweenEvictionRunsMillis="10000"
minEvictableIdleTimeMillis="30000"
removeAbandoned="true"
removeAbandonedTimeout="120000"
logAbandoned="true"
testOnBorrow="true"
testWhileIdle="true"
validationQuery="select 1"
driverClassName="com.mysql.jdbc.Driver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

仍然不确定为什么所有 3 个 DB 连接都卡在网络 IO 读取中,但是鉴于上面的配置,我希望 Tomcat 在所有现有连接都忙时创建额外的连接。

我有 8 个其他 Beanstalk 应用程序使用相同的设置,但是只有这个特定的应用程序有这种奇怪的池行为和网络 IO 问题。

你有什么建议?

非常感谢。

【问题讨论】:

【参考方案1】:

正如http://bugs.mysql.com/bug.php?id=31353 所建议的,您可能遇到了不安全的线程问题。

【讨论】:

谢谢。根据bug报告和其他在线讨论,我在MySQL JDBC连接字符串中添加了“socketTimeout=30000”,去掉连接驱逐设置和连接放弃设置,问题终于解决了。

以上是关于Tomcat JDBC 池连接全部卡在 Socket Read 上,没有创建新连接的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 连接池创建太多连接,卡在睡眠模式

Tomcat JDBC连接池(Tomcat 9)

Spring boot (11) tomcat jdbc连接池

如何记录 Tomcat 7 JDBC 连接池、连接创建

测试 Tomcat 的 JDBC 池连接

Tomcat 和 JDBC 连接池