前言:

项目部署上线后经过一段时间的运行,发现服务进程正常,可接口请求不通,重启服务就会正常,重启隔断时间还会出现,一般这种情况称之为服务假死。

一 排查思路

1.1 确定接口请求入口是否正常,排除外部原因;

1.2 查看服务日志,排查是否有明显的错误情况,针对错误情况处理;

1.3 服务所在机器的网络、磁盘、CPU、内存等进行逐一排查是否被占满;

1.4 查看服务对应的端口的情况;

1.5 通过jstack查询线程信息

二 查看服务对应的端口的情况

查看该端口详细的情况,如下:协议类型、源ip+port、tcp协议状态等信息,这里主要关注tcp协议的连接数量和每条连接对应的状态。

netstat -an |grep 8808

springboot SpringContextShutdownHook 自动停止了 springboot进程自动掉线_假死排查

 还可以通过grep具体的tcp状态码来确定当前tcp端口的连接数量及情况。

netstat -an |grep 8808 |grep CLOSE_WAIT

springboot SpringContextShutdownHook 自动停止了 springboot进程自动掉线_后端_02

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

springboot SpringContextShutdownHook 自动停止了 springboot进程自动掉线_服务假死_03

 三 通过jstack查询线程信息

# 查看服务进程ID
ps -ef |grep label 
# 查看进程的线程信息
jstack $PID 
# 线程进行归并到txt文件中
jstack $PID > jstack.txt

先找到该进程的pid,然后通过jstack命令导出线程信息,并下载到本地。

在jstack.txt中搜索DeadThread无果,继续搜索BLOCKED,发现了线程阻塞,如:

springboot SpringContextShutdownHook 自动停止了 springboot进程自动掉线_服务假死_04

java.lang.Thread.State 线程的状态:

NEW:至今尚未启动的线程的状态。

RUNNABLE:可运行线程的线程状态。处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。 

BLOCKED:受阻塞并且正在等待监视器锁的某一线程的线程状态。处于受阻塞状态的某一线程正在等待监视器锁,以便进入一个同步的块/方法,或者在调用 Object.wait 之后再次进入同步的块/方法。 

WAITING:某一等待线程的线程状态。某一线程因为调用下列方法之一而处于等待状态。 

TIMED_WAITING:具有指定等待时间的某一等待线程的线程状态。某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态。

TERMINATED:已终止线程的线程状态。线程已经结束执行。

hystrix-microservice-label-compass-6是tomcat处理请求的线程名称,可以看出大多数线程都被blocked,这可能就是发生假死的根源。分析得出是服务交互打开连接超时时间设置太长,修改超时时间观察一段时间服务,在未发生服务假死,问题圆满结束。