背景:
随着内网单设备登录的推广,顺便解决了扫码登录不改密码的问题,但是经过上线之后很多人集中修改了密码,并发不高但是依然对后端产生了一定的冲击和影响。
现象:
登录的web系统调用后端登录服务超时,且收到钉钉报警。用户修改密码之后无法登录gitlab相对严重。
服务依赖路径:
登录 web→登录的后端服务-->同步ldap服务器的服务→ldap服务器
现场保留&问题分析:
由于修改密码会触发同步到ldap服务器的操作,所以没有直接看登录相关工程的日志,直接到同步ldap服务器的服务的日志里面查看,发现controller代码中只有打印入参,没有出参,说明线程出现阻塞了。
1.使用命令查看服务器现状:top
2.使用命令查看同步ldap服务器的服务的进程id:ps -ef | grep ldap
3.使用命令查看同步ldap服务器的服务的线程运行情况: top -H -p pid
以上均未发现CPU,内存占用特别高的情况,推测可能是由于线程出现阻塞导致无法响应请求,使用下面的命令查看所有线程堆栈状态:
-
sudo jstack -l pid
发现大量BLOCKED状态的线程:
{69A1680B-674C-4BB8-860E-80A66F482695}_20190826160044.jpg
5.根据日志和分析可知由于连接Ldap服务器超时或者迟迟无响应导致线程阻塞,进而上游无法响应用户,出现问题。根据代码和场景可知连接ldap服务器操作完之后会释放,所以不能做长连接或者连接池优化处理。
临时方案:
重启线上服务,出问题用户重新修改密码可正常登录gitlab。
目前状态:
已对登录 服务后端工程调用 同步ldap服务器的服务工程的代码做异步处理,解决超时问题。
下一步方案:
说明:由于这个问题之前就出现过,在别的服务中做过类似优化,因为ldap服务器无法快速响应调用方,导致超时报错,线程阻塞,正常情况下大概能支持的量是1分钟2-4个调用量。
1.联系运维查找ldap链接问题
2.调用方做异步定时+限流处理,也就是说异步仅仅解决了登录web工程→登录后端工程的超时问题,但是如果同时有超过20个人在1分钟内发起修改密码则可能会导致这种情况出现。
线程状态相关:https://www.cnblogs.com/zyhxhx/p/4564953.html
思考
1.使用命令查看进程内线程数量
pstree -p pid |wc -l
2.使用命令查看进程内线程栈情况
jstack -l pid
3.使用命令查看进程内线程状态分布
jstack -l pid | grep 'java.lang.Thread.State' | awk '{print $2 $3 $4 $5}' | sort | uniq -c
4.通过上面的命令就可以在服务无响应的时候发现进程内线程状态,帮助定位问题
5.出现这种情况是否可以进行报警呢,比如3中的命令结果如下:
12 RUNNABLE
15 TIMED_WAITING(onobjectmonitor)
8 TIMED_WAITING(parking)
3 TIMED_WAITING(sleeping)
3 WAITING(onobjectmonitor)
12 WAITING(parking)
没有BLOCKED,如果有的话超过一定值是否可以报警呢?
网友评论