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 上,没有创建新连接的主要内容,如果未能解决你的问题,请参考以下文章