如何防止业务进程被OOM kill

OOM Killer 的全称叫 Out Of Memory Killer。
本文主要介绍:

  • Out-Of-Memory killer
  • 如何防止业务进程被OOM kill
  • Linux shell特殊变量含义

Out-Of-Memory killer

Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉。
典型的情况是:某天一台机器突然ssh远程登录不了,但能ping通,说明不是网络的故障,原因是sshd进程被OOM killer杀掉了(多次遇到这样的假死状况)。重启机器后查看系统日志/var/log/messages会发现Out of Memory: Kill process 1865(sshd)类似的错误信息。

具体的代码和算法可以参考 mm/oom_kill.c,注释写的很清楚。
https://github.com/torvalds/linux/blob/master/mm/oom_kill.c

防止业务进程被OOM kill

防止重要的系统进程触发(OOM)机制而被杀死:可以设置参数/proc/PID/oom_adj为-17,可临时关闭linux内核的OOM机制。内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的oom分数可以/proc/PID/oom_score中找到。我们运维过程中保护的一般是sshd和一些管理agent。

也就是说如果想要业务进程加入免杀列表,在知道业务进程id的情况下,可以做如下操作:

1
echo -17 > /proc/$PID/oom_adj

此外如果业务进程是通过shell脚本拉起,那么脚本里面启动业务进程前,可加入下面语句,将即将启动的业务进程加入免杀列表:

1
echo -17 > /proc/$$/oom_adj

Linux shell特殊变量含义

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2
$# 传递给脚本或函数的参数个数
$* 传递给脚本或函数的所有参数
$@ 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同
$? 上个命令的退出状态,或函数的返回值
$$ 当前Shell进程ID。对于 Shell 脚本,就是当前脚本所在的进程ID。

参考资料

Linux内核OOM机制的详细分析和防止进程被OOM杀死的方法
理解和配置 Linux 下的 OOM Killer
每个程序员都该了解一点 Linux 内存管理知识
linux bash Shell特殊变量

如果你觉得本文对你有帮助,欢迎打赏