tomcat假死 长时间GC导致服务不可用问题排查

时间:2024-04-04 22:06:11

前言:

   最近一段sso单点登录系统经常收到服务不可用自动重启的报警邮件,因为有做集群,影响较小,所以拖了几个月才开始着手解决这个问题。下面记录一下本次问题解决的过程(有走一些弯路),以做总结,也希望能给正在排查像试问题的同学一些启发:

先看看我的监控脚本

通过crontab 来监听重启

#!/bin/sh
    _status=`curl -I -m 40 -o /dev/null -s -w %{http_code} 127.0.0.1`
    echo status  $_status
    if [ $_status -ne 200 ] && [ $_status -ne 302 ]
    then
       echo start engine......
	 aws sns publish --message " sso2 检测到web不可用,自动重启" --topic arn:aws-cn:sns:cn-north-1:XXXX:aws-warning
	#sleep 180
        /usr/bin/sudo /usr/share/tomcat/bin/shutdown.sh 
	sleep 5
	/usr/bin/sudo ps -ef | grep 'tomcat'|grep '-server' | grep -v grep| awk '{print $2}' | xargs sudo kill -9 
	sleep 2 
	/usr/bin/sudo /usr/share/tomcat/bin/startup.sh 
    fi

这边是通过监听本机127.0.0.1 http状态是否正常来判断服务是否可用的,不等于200或者302时发送报警通知,并且自动重启tomcat;

1,怀疑连接数过高,服务器负载压力 服务器为 t2.medium(2cpu,4GB)

当我收到报警邮件的时候,我先连接上服务器,查看tomcat进程确实还在,查看服务器连接情况

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

发现有400多的close_wait,查看具体的close_wait。发现都是与aws elb负载均衡器的连接。因为那边默认60秒超时自动断开后,服务器无发响应,所以保持close_wait状态;

2,查看服务器cpu监控

tomcat假死 长时间GC导致服务不可用问题排查

发现当报警发生时,服务器cpu为100%;继续寻找cpu高的原因;

3,查看报警时cpu都在干嘛

修改报警脚本,当发送报警邮件后,让其sleep 180秒再重启,180秒的时间可以让我找到cpu高的进程数,然后再重启,就不影响用户使用了;

1,查看tomcat pid 

 ps -ef|grep tomcat   

2,查看cpu高的线程

top -H -p 26129

3,找到cpu 100%的线程id,转16进制

printf "%x\n" 26213

4.打印该线程堆栈

jstack 26129 |grep 6665 -A 30

通过堆栈信息发现居然是在进行GC操作,-----这很令我感到意外,因为这个服务器只做单点登录的事情,理论上是不会消耗过大内存的。并且从报警邮件的频率来看没有规律。有时候间隔2小时。有时候2天,并且日志里没有oom error日志;

4,查看内存堆栈

既然发现是因为GC操作导致的cpu过高,那么就查看报警时的堆栈信息就好了,

首先修改脚本,在重启tomcat之前 打印堆栈信息

/usr/bin/sudo ps -ef | grep 'tomcat'|grep '-server' | grep -v grep| awk '{print $2}' | xargs  sudo jmap -dump:live,format=b,file=heap.bin

5,通过MAT工具分析heap.bin

tomcat假死 长时间GC导致服务不可用问题排查

可以看到这个线程使用了1.6GB的内存。看看它到底在干嘛。

tomcat假死 长时间GC导致服务不可用问题排查

原来是在查询数据库内容。为什么这个接口会需要这么大的内存呢,排查代码发现,原来当用户调用修改密码接口没有输入邮箱或者手机号,这个接口居然没有做参数为空判断,直接去mysql查询用户表,2000w+的用户信息直接把内存撑爆了。

总结

对外接口不能过分依赖前端的表达校验,这个问题在测试线无法重现是因为数量级的不同,同时非重要的分支,测试人员也交容易忽略;通过这次的问题排查,发现了arthas这个工具,还是有不错的收获