问题介绍

测试服务器突然无法连接,ssh登录不上。只有重启才能解决。重启一天后,又连接不上了。

于是有了下面的排查过程,最终发现是有个java程序一直在创建线程,导致线程达到服务器最大数量,服务器崩溃。

1. 重启服务器

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

fork faild:Cannot allocate memory

以为是内存满了

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

2. 修改最大线程数

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

查看最大进程数 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

3. 查找线程最大的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程序的线程数不断增长。

4. 导出问题程序的线程日志

[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)

5. 找到问题代码

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

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

这就是问题根源。

	private void listDeviceFiles() {
		
		new Thread(new Runnable() {
			@Override
			public 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();
	}

6. 解决方案

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持Devmax。

记一次线程爆满导致服务器崩溃的问题排查及解决的更多相关文章

  1. iOS:核心图像和多线程应用程序

    我试图以最有效的方式运行一些核心图像过滤器.试图避免内存警告和崩溃,这是我在渲染大图像时得到的.我正在看Apple的核心图像编程指南.关于多线程,它说:“每个线程必须创建自己的CIFilter对象.否则,你的应用程序可能会出现意外行为.”这是什么意思?我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文).这在coreImage的上下文中是否有意义?

  2. ios – 多个NSPersistentStoreCoordinator实例可以连接到同一个底层SQLite持久性存储吗?

    我读过的关于在多个线程上使用CoreData的所有内容都讨论了使用共享单个NSPersistentStoreCoordinator的多个NSManagedobjectContext实例.这是理解的,我已经使它在一个应用程序中工作,该应用程序在主线程上使用CoreData来支持UI,并且具有可能需要一段时间才能运行的后台获取操作.问题是NSPersistentStoreCoordinator会对基础

  3. ios – XCode断点应该只挂起当前线程

    我需要调试多线程错误.因此,为了获得生成崩溃的条件,我需要在代码中的特定点停止一个线程,并等待另一个线程到达第二个断点.我现在遇到的问题是,如果一个线程遇到断点,则所有其他线程都被挂起.有没有办法只停止一个线程,让其他线程运行,直到它们到达第二个断点?)其他更有趣的选择:当你点击第一个断点时,你可以进入控制台并写入这应该在该断点处暂停当前上下文中的线程一小时.然后在Xcode中恢复执行.

  4. ios – 在后台线程中写入Realm后,主线程看不到更新的数据

    >清除数据库.>进行API调用以获取新数据.>将从API检索到的数据写入后台线程中的数据库中.>从主线程上的数据库中读取数据并渲染UI.在步骤4中,数据应该是最新数据,但我们没有看到任何数据.解决方法具有runloops的线程上的Realm实例,例如主线程,updatetothelatestversionofthedataintheRealmfile,因为通知被发布到其线程的runloop.在后台

  5. ios – NSURLConnectionLoader线程中的奇怪崩溃

    我们开始看到我们的应用启动时发生的崩溃.我无法重现它,它只发生在少数用户身上.例外情况是:异常类型:EXC_BAD_ACCESS代码:KERN_INVALID_ADDRESS位于0x3250974659崩溃发生在名为com.apple.NSURLConnectionLoader的线程中在调用时–[NSBlockOperationmain]这是该线程的堆栈跟踪:非常感谢任何帮助,以了解可能导致这种崩

  6. ios – 合并子上下文时的NSObjectInaccessbileExceptions

    我尝试手动重现,但失败了.是否有其他可能发生这种情况的情况,是否有处理此类问题的提示?解决方法在创建子上下文时,您可以尝试使用以下行:

  7. ios – 从后台线程调用UIKit时发出警告

    你如何处理项目中的这个问题?

  8. ios – 在SpriteKit中,touchesBegan在与SKScene更新方法相同的线程中运行吗?

    在这里的Apple文档AdvancedSceneProcessing中,它描述了更新方法以及场景的呈现方式,但没有提到何时处理输入.目前尚不清楚它是否与渲染循环位于同一个线程中,或者它是否与它并发.如果我有一个对象,我从SKScene更新方法和touchesBegan方法(在这种情况下是SKSpriteNode)更新,我是否要担心同步对我的对象的两次访问?解决方法所以几天后没有回答我设置了一些实验

  9. ios – 在后台获取中加载UIWebView

    )那么,有一种方法可以在后台加载UIWebView吗?解决方法如果要从用户界面更新元素,则必须在应用程序的主队列(或线程)中访问它们.我建议您在后台继续获取所需的数据,但是当需要更新UIWebView时,请在主线程中进行.你可以这样做:或者您可以创建一个方法来更新UIWebView上的数据,并使用以下方法从后台线程调用它:这将确保您从正确的线程访问UIWebView.希望这可以帮助.

  10. ios – 何时使用Semaphore而不是Dispatch Group?

    我会假设我知道如何使用DispatchGroup,为了解问题,我尝试过:结果–预期–是:为了使用信号量,我实现了:并在viewDidLoad方法中调用它.结果是:从概念上讲,dispachGroup和Semaphore都有同样的目的.老实说,我不熟悉:什么时候使用信号量,尤其是在与dispachGroup合作时–可能–处理问题.我错过了什么部分?

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部