2017-03-16 42 views
0

DB操作のためにjava.net.SocketInputStream.socketRead0(ネイティブメソッド)で時々Webアプリケーションスレッドがスタックする問題に直面しています。私のアプリサーバーとDBサーバーは異なるVMに存在します。私はDBプール 後は、私はDBサーバ(MySQLの5.6.34)でチェックプール構成Java Webアプリケーションのスレッドがjava.net.SocketInputStream.socketRead0(ネイティブメソッド)のDB操作にスタックしています

<Resource name="jdbc/xyz" auth="Container" 
type="javax.sql.DataSource"  
maxTotal="100" 
maxIdle="30"  
factory= "com.XXX.tomcat.jndi.EncryptedDataSourceFactory"    

maxWaitMillis="10000" 
username="abc" password="abcdef" 
driverClassName="com.mysql.jdbc.Driver"  
url="jdbc:mysql://x.y.z.w:3306/some_db" 
testOnBorrow="true" validationQuery="SELECT 1"> 
</Resource> 

あるとしてプールするTomcatでのTomcat 7.0.57を使用していますJStack

"http-bio-9904-exec-10" #57 daemon prio=5 os_prio=0  tid=0x00007f1730007000 nid=0xfcd1 runnable [0x00007f171e6ee000] 
java.lang.Thread.State: RUNNABLE 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 
at java.net.SocketInputStream.read(SocketInputStream.java:170) 
at java.net.SocketInputStream.read(SocketInputStream.java:141) 
at com.mysql.cj.core.io.ReadAheadInputStream.fill(ReadAheadInputStream.java:101) 
at com.mysql.cj.core.io.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144) 
at com.mysql.cj.core.io.ReadAheadInputStream.read(ReadAheadInputStream.java:174) 
- locked <0x00000000f6a35bb8> (a com.mysql.cj.core.io.ReadAheadInputStream) 
at java.io.FilterInputStream.read(FilterInputStream.java:133) 
at com.mysql.cj.core.io.FullReadInputStream.readFully(FullReadInputStream.java:58) 
at com.mysql.cj.mysqla.io.SimplePacketReader.readHeader(SimplePacketReader.java:60) 
at com.mysql.cj.mysqla.io.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:48) 
at com.mysql.cj.mysqla.io.MultiPacketReader.readHeader(MultiPacketReader.java:51) 
at com.mysql.cj.mysqla.io.MysqlaProtocol.readPacket(MysqlaProtocol.java:521) 
at com.mysql.cj.mysqla.io.MysqlaProtocol.checkErrorPacket(MysqlaProtocol.java:723) 
at com.mysql.cj.mysqla.io.MysqlaProtocol.sendCommand(MysqlaProtocol.java:662) 
at com.mysql.cj.mysqla.io.MysqlaProtocol.sqlQueryDirect(MysqlaProtocol.java:950) 
at com.mysql.cj.mysqla.MysqlaSession.sqlQueryDirect(MysqlaSession.java:431) 
at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1974) 
- locked <0x00000000f6a2ce30> (a com.mysql.cj.jdbc.ConnectionImpl) 
at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1936) 
at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:891) 
- locked <0x00000000f6a2ce30> (a com.mysql.cj.jdbc.ConnectionImpl) 
at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:795) 
. 
. 
. 
. 

の下 ご覧ください一般的なログでは、クエリが数分後にDBサーバーに到達していることがわかりました(5〜20分)。 クエリー(両方の挿入/選択)が秒単位で実行されることがあります。

アプリレベルのTCPダンプでも、5〜20分の遅延がある場合と同じ結果が表示されます。

観測の一部: 要求が発生すると15分後に応答が得られ、5分後から10分後にはすべてのクエリが次の30分間スムーズに機能します-40分。

使用されるMySQLドライバは5.1.0です。

問題の原因を特定するのを手伝ってください。

答えて

0

アトラス私は問題を抱えています。同様の問題に直面している人々は、同じことを試すことができます。 私はネットワーク内にあるファイアウォールの結果をactullyでした。接続プールの設定を使用して解決しました。 最終的なプール構成によって、私は問題なく動作しました。

<Resource name="jdbc/xxx" 
    auth="Container" 
    type="javax.sql.DataSource" 
    factory="com.yyy.tomcat.jndi.EncryptedDataSourceFactory" 
    username="xyz" 
    password="abc" 
    driverClassName="com.mysql.jdbc.Driver" 
    url="jdbc:mysql://x.x.x.x:3306/abc?enableQueryTimeouts=true&amp;autoReconnect=true&amp;autoReconnectForPools=true" 
    initialSize="0" 
    maxTotal="100" 
    maxActive="100" 
    minIdle="0" 
    maxWait="1000" 
    testOnBorrow="true" 
    testWhileIdle="true" 
    validationQuery="SELECT 1" 
    validationInterval="30000" 
    validationQueryTimeout="1" 
    timeBetweenEvictionRunsMillis="30000" 
    minEvictableIdleTimeMillis="30000" 
    removeAbandonedTimeout="10" 
    removeAbandoned="true" 
    logAbandoned="true" 
    logValidationErrors="true" 
    connectionProperties="[enableQueryTimeouts=true]" 
    jdbcInterceptors="ConnectionState;QueryTimeoutInterceptor(queryTimeout=1);SlowQueryReport;ResetAbandonedTimer"> 
関連する問題