首先背景是 [2019-11-04 线上服务无响应]https://www.jianshu.com/p/ba1d72ade525,当时服务长时间停止,错误日志也不输出,所以百思不得其解,到现在已经一个多月了,每次的解决办法都是重启重启再重启,虽繁琐,但是快还有效,所以治标不治本啊.当今天问题再次出现的时候,我忍无可忍,便一通操作.
导出堆栈文件
因为好多服务都在这台机器上,只是登录服务卡死,经过确认,其他服务没有受到影响.所以排除jvm 长时间gc的可能.便查找对应服务的进程号,使用命令导出对应进程的堆栈文件
jstack 6760 >sso.txt # 6760 就是进程号
将文件从服务器下载下来
sz sso.txt # 也有其他的下载命令,我这个是使用了secureCRT工具自带的
由于科技的发达,时代的进步,现在可以直接输入网址,上传文件,在线分析堆栈文件了
这是我使用的网站https://fastthread.io/
,打开后长这样.
英文不熟练没有关系,看自己能看懂的就行,右边有个选择文件,点击一下 ,上传你的堆栈文件,然后点击analyze.稍等片刻,便帮你分析出来,如下图
image.png
有三个颜色不知道看哪个?看不懂没关系,哪个颜色使你焦虑,你就点哪个.如图点击橙色的waiting,
image.png
进行分析
这个是我的报错异常,公司部分代码模糊处理了,不过也能看出来,在redis获取resource的时候产生了报错,说明代码在调用的时候可能没有正确处理连接,有可能使用完没有及时关闭,导致程序假死.我这个找到代码后,前后查看了一下,确认代码中有一处使用redis资源后没有及时关闭连接.
进行模拟调用后,发现确实会产生问题.随机编写关闭资源的代码,问题解决.但是还有一个为什么程序会卡死不报错的问题还困扰着我,于是,仔细翻看配置,发现我的redis 配置里有一行代码
max-wait: -1
这行我在百度后发现是这么解释的
image.png
所以个人感觉当连接池资源没有及时关闭后,就会造成获取redis资源的线程阻塞,由于配置了-1,就会导致一直阻塞下去,并且不会报错,每次用户请求就会导致服务器去创建一个线程来响应用户的服务,一般服务器默认是200多个线程,超出这个后,服务器就会停止服务,也就会导致假死
解决方案
连接及时关闭,配置max-wait 为100或者只要是正数就可以,这个配置会在获取资源的时候如果获取不到在你配置的时间后报错,便于快速解决问题
总结
多看书,多学习,多时间,别怕懒
网友评论