Java Web 应用程序线程在 java.net.SocketInputStream.socketRead0( native 方法)中因数据库操作而卡住

标签 java mysql multithreading tomcat connection-pooling

我遇到的问题是,有时 Web 应用程序线程会卡在 java.net.SocketInputStream.socketRead0( native 方法)以进行数据库操作。我的应用程序服务器和数据库服务器位于不同的虚拟机中。 请在下面找到 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 池作为数据库池 以下是池化配置

 <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 分钟之间变化)。 有时查询(包括插入/选择)会在几分之一秒内执行。

在应用级别的 TCP 转储中,也显示了相同的结果,其中有 5-20 分钟的延迟。

一些观察: 有一个时间段,例如 5-10 分钟,如果请求被触发,响应将在 15 分钟后获得,5-10 分钟之后,所有查询将在接下来的 30-40 分钟内顺利进行。

使用的Mysql驱动是5.1.0。

请帮助我确定问题所在。

最佳答案

终于找到问题了。遇到类似问题的人可以尝试一下。 这实际上是我网络中的防火墙的结果。我使用连接池设置解决了它。 最终的池配置使它对我有用。

<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">

关于Java Web 应用程序线程在 java.net.SocketInputStream.socketRead0( native 方法)中因数据库操作而卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42833576/

相关文章:

java - 如何在java中用遗传算法求解多项式方程?

python - python函数是线程安全的吗? (特别是这个?)

java - 在 Java 中还有什么可以用作 ServiceLoader 的替代品?

java - 未指定 maxSize 时,Google Guava Cache 逐出 SIZE 条目

java - Java 中的构造函数本质上是静态的还是非静态的?

c# - 尝试启动多个线程时索引超出数组范围

multithreading - 这种确保临界区不被中断的算法有什么问题?

mysql - 数据库中的库存架构

MySQL 选择带有数组信息的内容

php - 我可以为 MySQL 中的列指定特定的可选值吗