性能问答>tomcat假死,jstack日志发现ClientPoller丢失,NioEndpoint.countUpOrAwaitConnection()到达连接上限阻塞>
8回复
1年前

tomcat假死,jstack日志发现ClientPoller丢失,NioEndpoint.countUpOrAwaitConnection()到达连接上限阻塞


环境参数
  • 操作系统Linux
  • 操作系统版本CentOS 7.0 64/3.10.0-1127.13.1.el7.x86_64
  • JDK版本JDK8
  • 内存32GB
  • CPU核数16
  • 操作系统位数64位
jstack2130.log389.28KB
查看详情

环境

  • 生产环境应用服务假死,基于SpringCloud Dalston.SR4 + SpringBoot1.5.6.RELEASE + Tomcat8.5.16
  • Linux环境
>$ uname -a
Linux tst-center-login-temp 3.10.0-1127.13.1.el7.x86_64 #1 SMP Tue Jun 23 15:46:38 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

现象

  • 应用服务出现假死,netstat发现该服务进程大量close_wait
$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
SYN_RECV 8
CLOSE_WAIT 7085
ESTABLISHED 272
FIN_WAIT1 1
FIN_WAIT2 3
TIME_WAIT 251
  • ss -lnt,tomcat设置的backlog为800,全连接被打满
>$ ss -lnt
State      Recv-Q Send-Q                                                                                       Local Address:Port                                                                                         Peer Address:Port
LISTEN     801    800                                                                                                      *:8210                                                                                                    *:*

  • jstack发现日志缺少ClientPoller,同时Acceptor到达连接上限阻塞在NioEndpointd的Acceptor.countUpOrAwaitConnection()
"http-nio-8210-Acceptor-0" #53 daemon prio=5 os_prio=0 tid=0x00007f36a8837000 nid=0xdc1 waiting on condition [0x00007f36636f5000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000856cfa08> (a org.apache.tomcat.util.threads.LimitLatch$Sync)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
	at org.apache.tomcat.util.threads.LimitLatch.countUpOrAwait(LimitLatch.java:117)
	at org.apache.tomcat.util.net.AbstractEndpoint.countUpOrAwaitConnection(AbstractEndpoint.java:1074)
	at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:745)

求助

从jstack日志中发现ClientPoller线程丢失,实在是百思不得其解,求求路过的好心人帮助下迷路的孩子

3722 阅读
请先登录,再评论

http-nio-8210-Acceptor我看只有一个线程,理论上上是不是应该有至少两个线程,那真正的问题是不是说有一个Acceptor线程退出了,而Acceptor的选择是不是可能类似一致性hash算法一样会选一个Acceptor来处理,比如可能存在两个队列,这两个队列分布对应一个Acceptor线程,那因为某个线程退出了,而导致队列一直没有被消费,可以进一步内存Dump看下是否存在这种队列,因此我的一个大概建议是
1. dump一个正常环境的系统线程,看看是否有多个Acceptor线程
2. 如果确定是有多个的,那就是有线程退出了,内存Dump下看看队列是不是很大

如果都符合就分析Acceptor线程为啥会退出,看看逻辑上哪里可能存在异常没有捕获之类的场景

11年前
回复 你假笨:

👍多谢,我升级后监控看看

1年前回复
回复 一飞呀:

这样看下来,Tomcat存在bug的可能性比较大,可以到官网去找一下,或者升级到相对高级的版本

1年前回复
查看更多