记一次线程爆满导致服务器崩溃的问题排查

2023-10-29 05:36

本文主要是介绍记一次线程爆满导致服务器崩溃的问题排查,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

记一次线程爆满导致服务器崩溃的问题排查

重启服务器

  • 重启后,ssh连接发现下面问题

  • fork faild:Cannot allocate memory

  • 在这里插入图片描述

  • 以为是内存满了

  • 于是,free -h,查看内存情况,还有,观察一段时间后,内存没多大变化

  • 在这里插入图片描述

修改最大线程数

  • 经过各种百度,都说可以通过修改服务器的最大线程数来解决,于是我也这么干了。当时做的时候没有截图,所以下面截图是网上找的,凑合看看。

  • 查看最大进程数 sysctl kernel.pid_max

  • 在这里插入图片描述

  • ps -eLf | wc -l查看 进 程数

  • 修改最大 进 程数后系统恢复

  • echo 1000000 > /proc/sys/kernel/pid_max
    
  • 永久生效

  • echo "kernel.pid_max=1000000 " >> /etc/sysctl.conf
    sysctl -p
    

查找线程最大的java程序

  • 上一步扩大了线程数量后,感觉有点不对,因为之前没有这么配置都可以正常运行,为什么突然服务器挂了呢?肯定是有程序在作怪。
    于是决定找出占用线程最多的程序。回顾最近几天,服务器中只部署了几个springboot程序。问题一定出在它们之中。

  • 查看线程数量前20的java程序

  • ps -Lef |awk ‘{sum[$2]++}END{for(pid in sum) print pid, sum[pid]}’|sort -nr -k 2|head -n 20
    
  • [root@se-test-lky01 ~]# ps -Lef |awk '{sum[$2]++}END{for(pid in sum) print pid, sum[pid]}'|sort -nr -k 2|head -n 20
    16074 3100
    31386 1226
    20120 1072
    19548 985
    9697 829
    3005 796
    641 344
    19016 324
    16924 315
    17870 300
    6417 293
    8351 171
    7332 168
    18259 167
    19821 161
    16311 157
    18433 151
    18048 136
    14347 104
    2559 100
    
  • 观察一段时间后,发现进程id为16074的java程序的线程数不断增长。

导出问题程序的线程日志

  • [root@se-test-lky01 ~]#jstack 16074 >thread_dump.log
    
  • 分析日志,发现下面情况,线程数量不断增加,代码位置在FtpMonitorProcess.java:85

  • "Thread-4655" #4774 prio=5 os_prio=0 tid=0x00007f84aa2fe000 nid=0xd408b waiting for monitor entry [0x00007f802b704000]java.lang.Thread.State: BLOCKED (on object monitor)at cn.cloudwalk.bat.util.http.FtpUtil.connect(FtpUtil.java:246)- waiting to lock <0x00000006c09c1888> (a java.lang.Class for cn.cloudwalk.bat.util.http.FtpUtil)at cn.cloudwalk.bat.schedule.ftp.process.FtpMonitorProcess$1.run(FtpMonitorProcess.java:85)at java.lang.Thread.run(Thread.java:748)"Thread-4654" #4773 prio=5 os_prio=0 tid=0x00007f84aa2fc000 nid=0xd408a waiting for monitor entry [0x00007f802b805000]java.lang.Thread.State: BLOCKED (on object monitor)at cn.cloudwalk.bat.util.http.FtpUtil.connect(FtpUtil.java:246)- waiting to lock <0x00000006c09c1888> (a java.lang.Class for cn.cloudwalk.bat.util.http.FtpUtil)at cn.cloudwalk.bat.schedule.ftp.process.FtpMonitorProcess$2.run(FtpMonitorProcess.java:114)
    at java.lang.Thread.run(Thread.java:748)
    

找到问题代码

  • 发现这个方法每次被调用就会创建一个新的线程。而这个方法是被定时任务调用的,每10秒调用一次。

  • 问题就出在ftp没有配置,所以线程内执行ftp操作时,线程阻塞,没能释放。若ftp可用,则不会出现线程阻塞问题。

  • 这就是问题根源。

  • 	private void listDeviceFiles() {new Thread(new Runnable() {@Overridepublic void run() {logger.debug("开始获取[ftp-设备]文件...");try {String workDir = ftpConfig.getWorkdir();// 连接FTPClient ftpClient = FtpUtil.connect(ftpConfig);ftpClient.changeWorkingDirectory(workDir);ftpClient.changeWorkingDirectory(SubscribeDataTypeEnum.DEVICE_INFO.getKey().toString());FTPFile[] files = ftpClient.listFiles();for(FTPFile file : files) {decomposeFile(file,ftpClient);}ftpClient.logout();} catch (Exception e) {logger.error("ftp获取文件名出错:" + e.getMessage());}}}).start();}
    

解决方案

  • 不建议手动创建线程,改用使用线程池。

这篇关于记一次线程爆满导致服务器崩溃的问题排查的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/298580

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入