Java程序员可能这辈子都无法见到的史诗级线上问题——Linux系统的线程上限被干满了!

先简单描述下这次线上问题的原因和处理,大概就是另外一个同事发现配置nginx的时候,docker指令没办法用了,一用就会报错pthread_create failed,有点儿linux基础的都知道,这是创建新线程失败了。

但是,我就很好奇,什么样的情况下会把linux系统的线程上限给干满?最开始我怀疑的是这台服务器的线程上限设置得太小了,导致被干满了,但是随着我逐渐深入的查问题原因,我发现里面隐藏着一些不可告诉人的秘密------坨巨大的shit在我们项目里面。

问题描述

同时在修改了些nginx配置,重启docker的时候,告诉我出现了一个线程上问题,具体如下:

我立马登陆上服务器,用docker ps试了一下,果然这个服务的docker都用不了了,报错如下:

java 复制代码
-bash-4.2# docker ps
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0x7fde1873b387 m=3 sigcode=18446744073709551610

很显然,是docker ps的命令core了,core的具体原因是告诉我linux系统级别的函数pthread_create创建线程失败了,具体原因是资源不足。

问题原因

当然!遇到这种问题我肯定是不慌的,不就是线程上限达到了吗?肯定是线程上限设置得过小,让我们来查看一下Linux服务器的线程上限,命令如下:

查看最大进程数
java 复制代码
sysctl -a | grep pid_max

这不看不要紧,一看吓一跳,系统的线程上限设置是没有问题的,65536个线程数目,这是一般Linux系统的线程上限设置,所有问题都指向了一个可怕的结论,那就是有进程把最大线程数干满了。

系统内部进程总数

没办法,接着查查看系统内部的进程总数,一看接着吓一跳,线程数目来到了65040个,几乎干满了65535个线程的上限。

java 复制代码
pstree -p | wc -l

这个结果说明是系统线程被耗尽了,肯定代码有问题,线程资源没有释放。

top查看哪个进程占用线程数目最多
java 复制代码
top

最后通过top这个命令发现pid = 5346的进程线程数异常的高,我怀疑是5436这个进程对应的服务有问题,线程创建完了之后没有被释放。

ps -eLf查看这个进程到底创建了多少线程
java 复制代码
ps -eLf

问题解决

暂时解决方案

终于通过排查定位了问题是pid=5436这个服务中的代码有异常,创建的线程资源没有被及时的释放,导致整个linux服务器的最大线程数都被占满了。

为了暂时先解决这个问题,保障线上正常访问,我选择了先重启该服务,重启之后线程得到了释放,随即docker也恢复了正常。

java 复制代码
kill -9 5436

深入解决问题

这个问题的本质还是业务层面代码有问题,应该是什么地方的线程资源没有释放,导致最后占满了整个系统的线程资源。

后续我排查了项目代码,发现是IOT推送模块儿导致的,之前的老哥的websock没有采用netty之类的三方库,而是自己手动撸了一个websock的注册和推送逻辑。

而这部分的前端开发会频繁的去页面创建新的websock连接,每个websock连接在Java后台都会去new一个新的线程,然而前端完事儿之后没有释放websock连接,后台的推送模块儿也没有检测失效websock连接并关闭的逻辑。

这就导致最近前端在更改代码之后,干爆了后台Linux服务器的线程创建上限,我真的是一个大写的服!

后续解决的话是websock的推送模块儿全部改成使用netty的websock进行推送,所以这个故事告诉我们不要轻易的自己造轮子!

这个问题的另外一种可能

在网上搜索了这个错误,发现其它人也遇到了同样的错误,但是他们的错误大多数是由于系统线程上限设置较低造成的,而不是由于我这种服务线程把系统线程干满了。

这些问题的解决方案大概就是更改系统的线程上限,具体我就不赘述了,大家可以参考这篇文章

最后,欢迎关注微信公众号【浣熊say】

相关推荐
这里有鱼汤3 分钟前
“对象”?对象你个头!——Python世界观彻底崩塌的一天
后端·python
RainbowSea5 分钟前
跨域问题(Allow CORS)解决(3 种方法)
java·spring boot·后端
sniper_fandc2 小时前
SpringBoot系列—入门
java·spring boot·后端
Piper蛋窝8 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛11 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack11 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
315356691311 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong11 小时前
curl案例讲解
后端
一只叫煤球的猫12 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
大鸡腿同学13 小时前
身弱武修法:玄之又玄,奇妙之门
后端