一次针对服务器脚本诡异停止的问题发现及尝试的解决方案
因为这段时间需要在服务器上跑一些脚本,突然发现有时候脚本会突然结束,通过百度搜索发现是服务器内存不足出发了OOM killer机制,以下给出排查问题的方式及一些尝试的解决方案
问题发现
在服务器上运行脚本时,使用nohup命令执行命令,但是一段时间之后脚本总会莫名其妙的停止,虽然使用nohup命令中将标准输出重定向到了一个文件中,但是由于脚本中的输出有缓存,所以最后程序停止的信息没有重定向到文件中,因此决定去排查原因。
这里选择直接运行脚本,观察脚本输出结果,运行一段时间后,发现脚本的最后会直接输出killed,结果如下:
注意其中的29990\2431368的是脚本中打印的中间结果,为了方便查看脚本的执行过程,可以看到最后出现了Killed
于是这里通过百度发现了程序出现Killed的原因,猜想可能是因为内存不足的原因导致的,于是使用如下命令查看日志信息
cat /var/log/messages | grep "Out of"
当然百度中也有一些其他命令查看,如:journalctl -xb | egrep -i 'killed process' -C 5
,该命令可以查看kill进程的日志,也包括了Out of Memory的情况
尝试的解决方案
首先了解为什么进程会终止呢,这里跟Linux的内核机制OOM有关,这里不再讲解,大家可以查看链接:Linux有趣的内核机制:OOM
因为了解了是因为内存不足导致的,这里笔者已知的有以下3种解决方案
- 优化程序,减少程序不必要的内存
- 配置Linux的swap缓解内存(swap机制是使用磁盘空间来存储不必要的内存,从而从逻辑上达到扩充内存的目的)
- 升级服务器配置(只要有钱,一切都不是问题,手动狗头)
接下来笔者将采用前两种方式尝试问题的解决
1.优化程序
因为笔者使用的脚本是从文本文件(文本文件内容较多,有200w+数据)读取内容存入queue中,然后采用多线程技术从queue中取出数据,因此这里有两种优化方案:
- 将文本文件分成多个文件
笔者这里最开始想使用python脚本拆分文件,后来猜想Linux是否有相关命令可以直接使用,通过百度搜索查阅可以采用以下命令
wc -l {target_file}
:用来查看target_file有多少行
split -l {target_lines} {target_file} {result_suffix}
:其中target_file为需要切割的文件,target_lines表示按照多少行来切割文件,result_suffix表示最后得到的文件的前缀是什么
以上两个命令均可以在Linux中使用帮助文档查看更多的使用方法,wc --help
、split --help
笔者最后保证了每个文件最多为100000行,因此得到了20+个子文件,然后可以分别运行程序
- 减少线程数量
这里得根据实际的脚本内容来看,笔者的脚本有一个专门设置线程数量的参数,直接修改即可
2.配置Linux的swap
这里可以直接在Linux命令行中使用命令配置,如果Linux采用了宝塔面板,可以在应用程序中下载Linux工具箱使用可视化界面配置
具体的配置命令可以查看该文档:Linux实例SWAP分区的配置和常见问题处理
也可以采用宝塔面板配置,笔者的配置结果如下: