记一次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个?

 

posted @ 2022-04-27 15:55  huangyn  阅读(550)  评论(0)    收藏  举报