Amazon ElasticBeanstalk でホストされている Tomcat 7 アプリケーションと、Amazon RDS でホストされている MySQL 5.5 データベースがあります。データベース サーバーは 1 つの Tomcat アプリケーションのみを提供し、最大接続制限は 10,000 に設定されています。
ただし、数時間のアップタイムの後、DB 接続に奇妙なことが起こっています。
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 の問題を抱えています。
何を指示してるんですか?
どうもありがとうございました。