本文记录了一个非常奇葩的bug(进程莫名终止)的发现过程,详细记录了问题背后的原因和解决方法。背景本项目是一个接口自动化测试平台,需要对接自动化项目(每个自动化项目对应一个被测试的应用项目),每个自动化项目都是一个独立运行的进程。自动化项目使用springboot,配合maven插件运行,mvnspring-boot:run。平台对接了很多自动化项目,很多自动化项目的流程都运行在一台linux机器上。偶尔会莫名其妙的把自动化项目的进度卡死,需要重新上平台操作。自动化项目启动后,任务可以继续运行。直到系统规模扩大,自动化项目增多,自动化用例增多,任务运行时间变长,自动化项目莫名终止的概率增加。分析查看日志,发现自动化工程被终止的日志信息如下:[INFO]----------------------------------------------------------------------[信息]构建失败[信息]-------------------------------------------------------------------[信息]总时间:09:32分钟[信息]完成时间:2019-08-15T17:39:55+08:00[信息]]--------------------------------------------------------------------[错误]无法执行目标org.springframework.boot:spring-boot-maven-plugin:2.2.0.M5:在项目coupon_batch-Test上运行(default-cli):应用程序完成,退出代码:137->[Help1][ERROR][ERROR]要查看错误的完整堆栈跟踪,请使用-e开关重新运行Maven.[ERROR]使用-X开关重新运行Maven以启用完整的调试日志记录。[ERROR][ERROR]有关错误和可能的解决方案的更多信息,请阅读以下文章:[ERROR][Help1]http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException分析日志生成的原因,google:ERROR:MavenJVMterminated意外退出代码137作为参考,状态代码137(128+9)通常表示(可能因unix风格而异)。该过程因收到信号而终止。在这种情况下,信号9是SIGKILL和不可阻挡的kill。如果是这种情况,底层机器/操作系统需要更多虚拟内存。这可以通过适当地添加物理内存或交换空间来添加。您应该尝试增加机器的虚拟内存。注意:这也解释了为什么Jenkins重启(暂时)解决了这个问题。JenkinsMavenBuild137Error目前已经找到问题原因:linuxswap分区不足,导致进程被linuxOOMKillerkill掉。解题所需的背景知识1.什么是swap?交换空间是磁盘上的一个块。区域可以是分区、文件或它们的组合。简单的说,当系统的物理内存紧张时,Linux会把内存中不常访问的数据保存到swap中,让系统有更多的物理内存来服务于各个进程,当系统需要访问swap上存储的内容,然后将swap上的数据加载到内存中,也就是我们常说的swapout和swapin。2.为什么需要swap?对于一些大型的应用程序(如LibreOffice、视频编辑器等),在启动过程中会使用大量的内存,但是这部分内存往往只在启动时使用,后续运行中很少使用进程内存。通过swap,系统可以将这部分没有被使用的内存数据通过这种方式保存到swap中,从而释放出更多的物理内存供系统使用。很多发行版(比如ubuntu)的休眠功能都依赖于swap分区。当系统休眠时,内存中的数据会被保存到swap分区中,下次系统启动时数据会加载到内存中。它可以加快系统的启动速度,所以如果要使用休眠功能,就必须配置swap分区,而且大小必须大于等于物理内存。在某些情况下,物理内存是有限的,但是如果要运行耗内存的程序怎么办呢?这时候配置足够的swap空间就可以达到目的。虽然慢了点,但至少能跑起来。虽然在大多数情况下,物理内存是足够的,但是总会出现一些意想不到的情况,比如某个进程需要的内存比预期的多,或者某个进程发生了内存泄漏等。当内存不够时,就会触发内核的OOM杀手。根据OOMkiller的配置,会杀掉一些进程或者直接重启系统(默认是先杀掉内存消耗最多的进程),但是有了swap,就可以把swap当作内存使用。虽然速度有点慢,但至少给了我们调试、杀掉进程或者保存当前工作进度的机会。如果你看过Linux的内存管理,你就会知道,系统会尽可能多的使用空闲内存作为缓存,以加快系统的I/O速度,所以如果能把不常用的内存数据移到swap,有将更多的物理内存用于缓存,从而提高整体系统性能。3、swap的缺点上面介绍了swap的优点,那么swap的缺点呢?Swap存储在磁盘上,磁盘的速度比内存慢几个数量级。如果不断地读写swap,肯定会影响系统的性能,尤其是在系统内存非常紧张的情况下。交换空间的频率会很高,导致系统运行很慢,就好像死了一样。这时,增加物理内存是唯一的解决办法。由于系统会自动将不经常使用的内存数据移动到swap中,对于桌面程序来说,最小化后打开程序时可能会造成小卡顿,因为swap上的数据需要重新加载到内存中来。Linux交换空间(swapspace)采用的解决方法:添加交换文件#首先新建一个512M的文件作为交换文件,文件路径可以任意#fallocate这个命令依赖于文件系统,一些老文件系统不支持这个命令,比如ext2,#这种情况下可以用dd来达到同样的效果:#sudoddif=/dev/zeroof=/mnt/512MiB.swapbs=1024count=524288#Thefallocate和dd的区别是这样的:#fallocate是先声明这么多,然后文件系统在实际使用的时候分配真正的物理磁盘空间,也就是分配一点点,#anddd实际上写了512m的数据从物理磁盘空间开始。#所以作为测试,fallocate比较方便,因为一开始不需要写任何数据,需要速度快dev@dev:~$sudofallocate-l512m/mnt/512MiB.swap#修改文件权限,防止其他用户误操作修改文件dev@dev:~$sudochmod600/mnt/512MiB.swap#格式化为交换文件dev@dev:~$sudomkswap/mnt/512MiB.swap#Addnewfilestothesystemdev@dev:~$sudoswapon/mnt/512MiB.swap#此时可以看到系统中已经添加了新的swap文件,类型为file#这里可以看到第一个交换分区/dev/dm具有最高优先级-1已被使用24Kdev@dev:~$swapon-sFilenameTypeSizeUsedPriority/dev/dm-1partition52428424-1/dev/sdb1partition20961240-2/mnt/512MiB.swapfile5242840-3#从free命令的输出可以看出,经过前两轮添加swap分区和文件后,#现在系统的swap空间变成了3G(3144692K)dev@dev:~$freetotalusedfreesharedbuff/cacheavailableMem:5001923911295641996451516430820Swap:3144692243144668#另外为了保证我们新的交换文件在系统重启后自动加载,我们需要修改/etc/fstab文件dev@dev:~$sudosh-c'echo"/mnt/512MiB.swapnoneswapsw00">>/etc/fstab'Advanced:OOMKiller配置理解及Linux下OOMKiller的配置总结技术问题总是有原因的,就看你能不能找到技术问题如果你再深入,有很多地方可以学习,有bug就是学习机会。版权声明:本文为博主原创文章,遵循CC4.0by-sa版权协议,转载请附上原文出处链接及本声明。转载自openWrite
