我在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问题。
你有什么建议?
非常感谢。