当前位置:首页 > 科技数码

【0x00000006】案例研究:由于线程池使用不当而导致系统崩溃

前几天发现一台阿里云服务器无法使用web服务。

远程SSH登录不上,尝试几次登录上去之后,执行命令都显示

-bash: fork: Cannot allocate memory

一看以为是内存泄漏导致溢出。因为执行不了任何命令, 只能通过控制台重启服务器恢复服务。

初步排查

服务恢复后,查看系统日志,linux系统日志路径/var/log/messages,可通过journalctl命令查看,如

journalctl --since="2019-06-12 06:00:00" --until="2019-06-12 10:00:00" `

可查看since之后,until之前时间段的日志。除了发现crond[14954]: (CRON) CAN'T FORK (do_command): Cannot allocate memory 这个错误日志,未见其它异常(下面的sshd[10764]: error: fork: Cannot allocate memory应是ssh登录执行命名失败的日志)

通过阿里云-云监控-主机监控查看内存使用率指标,这段时间内,内存使用率一直在40%以下,基本可排除内存溢出的可能。

通过搜索查阅到进程数超过操作系统限制可能导致bash: fork: Cannot allocate memory的报错(参考: )。通过ps -eLf|wc -l查看当前进程线程数(ps -ef只打印进程,ps -eLf会打印所有的线程), 只有1000多个,故障时刻系统到底运行了多少线程已无从得知,只能持续跟进监测。

问题定位

几天后,再次通过ps -eLf|wc -l查看,发现线程数已达16000多个。直接执行ps -eLf可看到大量tomcat进程所产生的线程,猜测是不是线程死锁导致大量线程未完成一直hung在那里。

执行 jstack 进程号 > ~ 命令将进程所运行线程情况打印出来分析,发现大量的WAITING状态的线程,如下

"pool-19-Thread-1" #254 prio=5 os_prio=0 tid=0x00007f0b700a6000 nid=0x29a9 waiting on condition [0x00007f0b274df000] java.lang.T: WAITING (parking) at (Native Method) - parking to wait for <0x00000006ce3d8790> (a java.u$ConditionObject) at java.u(LockSupport.java:175) at java.u$Condi(AbstractQueuedSynchronizer.java:2039) at java.u(LinkedBlockingQueue.java:442) at java.u(ThreadPoolExecutor.java:1074) at java.u(ThreadPoolExecutor.java:1134) at java.u$Worker.run(ThreadPoolExecutor.java:624) at java.lang.T(Thread.java:748)

根据上述内容可看出线程在等一个条件,并且是在执行LinkedBlockingQueue.take方法的时候,查看该方法的java doc,当队列为空时,该方法将会一直等待直到有元素可用。

/** * Retrieves and removes the head of this queue, waiting if necessary * until an element becomes available. * * @return the head of this queue * @throws InterruptedException if interrupted while waiting */ E take() throws InterruptedException;

询问同事在哪里用到了LinkedBlockingQueue,同事回忆起不久前用线程池实现往阿里云OSS服务通过追加的方式上传文件功能,查看代码后发现问题——线程池没有关闭。为了使文件片段保存不存在错乱,每次保存文件时,都new了一个线程池对象,

ThreadPoolExecutor saveImgThreadPool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

但处理完后, 没有关闭这个线程池对象,这样线程池仍会通过take方法去取等待队列中是否还有未完成的线程任务,等待队列为空时将会一直等待,这样就导致大量的线程hung在这里了(基本是只要方法被调一次,就会产生一个hung住的线程),时间一长就达到系统所允许的最大限制(默认32768个),不能处理新任务,从而导致系统服务不可用。

延伸

  1. 线程状态为“waiting for monitor entry”:
  2. 意味着它 在等待进入一个临界区 ,所以它在”Entry Set“队列中等待。此时线程状态一般都是 Blocked:
  3. java.lang.T: BLOCKED (on object monitor)
  4. 线程状态为“waiting on condition”:
  5. 说明它在等待另一个条件的发生,来把自己唤醒,或者干脆它是调用了 sleep(N)。此时线程状态大致为以下几种:
  6. java.lang.T: WAITING (parking):一直等那个条件发生(本文案例即为此种场景);java.lang.T: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。
  7. 如果大量线程在“waiting for monitor entry”:可能是一个全局锁阻塞住了大量线程。如果短时间内打印的thread dump 文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。
  8. 如果大量线程在“waiting on condition”:可能是它们又跑去获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。所以如果你发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。也可能是如本文所提到的,由于程序编写不当所致。

参考:

我的个人博客地址:

我的头条空间:

我的github地址:

我的微信公众号:jboost-ksxy

——————————————————————

欢迎关注我的微信公众号,及时获取最新分享

1.《【0x00000006】案例研究:由于线程池使用不当而导致系统崩溃》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《【0x00000006】案例研究:由于线程池使用不当而导致系统崩溃》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/1956752.html

上一篇

0x000050,干货看这篇!基于异常的狩猎行为——自我保护触发自杀

下一篇

关于010区号我想说发现了吗?区号020-029的城市唯独没有026吗?

关于0x00000006我想说强制性Linux命令百科全书的开发-不损失稳定的利润。

关于0x00000006我想说强制性Linux命令百科全书的开发-不损失稳定的利润。

0x00000006相关介绍,戴尔服务通常在Linux系统上运行,因此需要了解Linux命令。 接下来将一一详细介绍一些常用的linux的命令 文件操作 远程登录与操作 磁盘挂载 进程管理 启动和结束 系统性能参数查看 网络数据抓...

【0x00000006】强制性Linux命令百科全书的开发-不损失稳定的利润。

【0x00000006】强制性Linux命令百科全书的开发-不损失稳定的利润。

0x00000006相关介绍,戴尔服务通常在Linux系统上运行,因此需要了解Linux命令。 接下来将一一详细介绍一些常用的linux的命令 文件操作 远程登录与操作 磁盘挂载 进程管理 启动和结束 系统性能参数查看 网络数据抓...

0x00000006专题之连接共享打印失败报告操作错误0x00000006

0x00000006专题之连接共享打印失败报告操作错误0x00000006

0x00000006相关介绍,windows 10主页中文版 朋友说平时可以正常访问的共享打印机突然打印不出来了。 这小手又开始痒痒了,不找到原因誓不放弃。 为了不混淆这几台电脑,设朋友的电脑为“客机”,找了另一台“测试机”,连接...

【0x00000006】专题Win10版本将出现各种计算机蓝屏代码百科全书

【0x00000006】专题Win10版本将出现各种计算机蓝屏代码百科全书

0x00000006相关介绍,很多深度技术合作伙伴都会遇到计算机蓝屏的问题。特别是现在大家都比较喜欢win10版本的电脑。那么,win10系统中常见的蓝屏代码是什么?(威廉莎士比亚、Northern Exposure(美国 电视剧...

【0x00000006】专题【干货】电脑高手之路:电脑蓝屏错误“0x00000006”怎么办?

  • 【0x00000006】专题【干货】电脑高手之路:电脑蓝屏错误“0x00000006”怎么办?
  • 【0x00000006】专题【干货】电脑高手之路:电脑蓝屏错误“0x00000006”怎么办?
  • 【0x00000006】专题【干货】电脑高手之路:电脑蓝屏错误“0x00000006”怎么办?
0x00000006专题之终极十六进制转换小程序,拿走也不感谢,叫我雷锋

0x00000006专题之终极十六进制转换小程序,拿走也不感谢,叫我雷锋

0x00000006相关介绍,上一期写了十六进制转换的文章【干货满分,十六进制奇妙转换】,推荐量阅读量创新低,不了解头条的算法机制,姑且怀疑与发布时间和内容形式有关吧。 再次整理思路,重新提供明了的干货,望各位看官多多支持,关注、...

0x00000006看这里!电脑又蓝屏了_代码含义百科全书

0x00000006看这里!电脑又蓝屏了_代码含义百科全书

0x00000006相关介绍,序列号代码含义 00x000000操作已完成。 10x00000001无效函数。 2 0x00000002 系统找不到指定的档案。 3 0x00000003 系统找不到指定的路径。 4 0x00000...

0x00000006,干货看这篇!计算机蓝屏代码百科全书

0x00000006,干货看这篇!计算机蓝屏代码百科全书

0x00000006相关介绍,号码代码含义 00x000000操作已完成。 1 0x00000001 不正确的函数。 2 0x00000002 系统找不到指定的档案。 3 0x00000003 系统找不到指定的路径。 4 0x00...