我面临的问题是,有时web应用程序线程卡在java.net.SocketInputStream.socketRead0(本地方法)的DB operations.My应用程序服务器和DB服务器驻留在不同的虚拟机。请查看下面的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)
.
.
.
.我使用tomcat 7.0.57和tomcat池化作为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>我检查了数据库服务器(Mysql 5.6.34)的一般日志,发现查询在几分钟后到达数据库服务器(在5-20分钟之间变化)。有时查询( insert/select)的执行时间只有几分之一秒。
在应用程序级别的TCP转储中也显示了相同的结果,其中存在5-20分钟的延迟。
一些观察:有一段时间,比如5-10分钟,在这段时间内,如果请求被触发,则在15分钟后获得响应,在这5-10分钟之后,所有查询将在接下来的30-40分钟内平稳地工作。
使用的Mysql驱动是5.1.0。
请帮助我找出问题所在。
发布于 2017-03-21 18:38:47
最后,我得到了面对类似问题的problem.People,可以尝试同样的问题。这实际上是我的网络中防火墙的结果。我使用连接池设置解决了它。最终的池配置使它对我来说是有效的。
<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&autoReconnect=true&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">https://stackoverflow.com/questions/42833576
复制相似问题