记一次mqtt线程驻留导致的cannot allocate memory
工作中遇到的问题
1.项目基本架构

2.遇到的问题
线上客户使用小程序时,出现有个操作没反应的情况,其他基本操作没问题
3.排查过程
1)模拟客户使用,确实是该操作没反应
2)charles代理看看接口情况

可以看到接口1-3都没啥问题,响应结果也是正确的,那么看一下接口4的具体返回结果

一看就后台服务器那边错误咯,那么转战服务器后台看日志咯
3)ssh登录 该接口对应的阿里云服务器后台
尝试ssh连接,gg,登录不上去

幸好我之前连接了(ssh工具连了,在问题发生前一直就没断开),再试试
![]()
看这个报错,像是内存不够了啊,然后网上一波搜索,参考 https://www.cnblogs.com/-xuan/p/15944359.html
4)利用阿里云平台ECS实例
阿里云服务器实例有个监控页面,可以看到服务器状态:CPU和内存使用率都没满

另外,阿里云服务器ECS实例也可以在网页上进行登录,但是当时也是登录不上去
问了客服,给了这个方法 https://help.aliyun.com/knowledge_detail/51673.html?spm=5176.22414175.sslink.1.536121ffqbEX7z,
后续也traceroute过,没看出问题(这里感觉抓错方向了)

5)重启
客户那边催得紧,我这边暂时又找不到问题点,就直接在阿里云平台上重启实例了
重启之后啥问题也没得!!!查看事发当时的后台tomcat日志, unable to create new native thread
无法新建本地线程,成功呼应上了cannot allocate memory

查了一下后台服务器配置

4.原因分析
那么直接原因:JVM无法创建本地线程,更深原因可能是
1.JVM内存分配问题,即OOM问题
2.系统内存不够用
3.连接数不够用
5.复现验证
当时做了复现测试,即模拟现场用户调用问题接口4(实际上现场用户不超过50个):
方法1:将小程序后台,转移到192.168.101.6上,进行1000线程测试,未发现同样的问题
方法2:给tomcat调优,再次加压测试,没问题

方法3:(开发给我科普的)使用jvisualvm工具查看线程情况(参考 https://www.cnblogs.com/huangyuanni/p/16145545.html)
6.最终结果
开发告诉我是mqtt相关线程驻留导致的,当时认为是线程驻留导致内存占用,JVM的内存分配不够了

开发代码改完之后,确实没再出现这个bug了哈哈哈
监测时不停刷新接口4(当时出现的情况图没有截取,下图凑合看看吧)
大致就是不停在创建thread,然后创建的这个thread一直驻留(图里只驻留了20秒左右),查了一下这个线程是mqtt用的

请教了一下开发当初代码咋改的,参考https://cloud.tencent.com/developer/article/1552599

查了下代码(修复过后的内容)

直到今天看了篇文章https://mp.weixin.qq.com/s/9blpS_TjKwgaGVsdsbKGGQ(里面直接剖析到了linux内核代码)
才反应过来可能是连接数超过系统限制了(结合内存还剩很多、线上并发量不大、其他接口响应正常来看)

关于linux最大连接数 https://www.cnblogs.com/ZhaoKevin/p/12310662.html
关于java线程与linux连接数关系 https://zhuanlan.zhihu.com/p/483878658
关于单进程最大线程数的解释,参考https://blog.csdn.net/wangfeng2500/article/details/41292505,也就是不超过1024个?
浙公网安备 33010602011771号