问题描述Linux内核有一种机制叫做OOMkiller(Out-Of-Memorykiller),它会监控那些占用过多内存的进程,尤其是那些瞬间消耗大量内存的进程,为了防止内存耗尽,内核会杀掉进程。一个典型的情况是:某天一台机器突然ssh远程登录失败,但是能ping通,说明不是网络故障,因为sshd进程被OOMkiller杀掉了(这种假死遇到过很多次)。重启机器后查看系统日志“/var/log/messages”,会发现类似“OutofMemory:Killprocess1865(sshd)”的错误信息。如何防止重要的系统进程被触发(OOM)机制杀死?只需一个技巧就可以轻松避免它。设置参数“/proc/PID/oom_adjto-17”可以暂时关闭Linux内核的OOM机制。内核会通过特定的算法为每个进程计算一个分数来决定杀死哪个进程。每个进程的OOM分数可以在“/proc/PID/oom_score”中找到。解决方法一、方法一:设置参数/proc/PID/oom_adj为-17如何防止mongod被杀,可以这样做:(1)编写脚本文件oomadj.sh,内容如下:#!/bin/bashnetstat-ntlup|grepmongod|awk'{print$NF}'|awk-F'/''{print$(NF-1)}'|whilereadPID;doecho-17>/proc/$PID/oom_adj;done(2)设置定时计划[root@mnkj-mongodb-01~]crontab-e*/1****/root/omadj.sh至于为什么用-17而不是其他值(默认值为0),这个是定义的由linux内核。查看内核源码可知:以linux-3.3.6版本的内核源码为例,路径为“linux-3.6.6/include/linux/oom.h”,阅读内核源码,“oom_adj”的可调值可以是15到-16,其中15最大-16最小,-17禁用OOM。“oom_score”计算为2的N次方,其中N是进程的“oom_adj”值,因此“oom_score”分数越高,越会被内核先杀死。2.方法二:修改内核参数禁用OOM机制#sysctl-wvm.panic_on_oom=1vm.panic_on_oom=1//1表示关闭,默认为0表示开启OOM#sysctl-p注:kernel-2.6.26之前版本的oomkiller算法不够准确,RHEL6.x版本2.6.32可以解决这个问题。子进程会继承父进程的oom_adj。OOM不适合解决内存泄漏(Memoryleak)的问题。有时free会检查内存是否还充足,但还是会触发OOM,因为进程可能会占用特殊的内存地址空间。OOMkiller是一种非常实用的机制,可以保证系统内存不被个别进程耗尽,但是在实际工作中,除了运行过多的进程会导致内存占用过大外,还有很多其他因素如:访问量增加,攻击等等。。这个时候我们不仅要用好OOMkiller,还需要注意服务器的资源使用情况。我们需要一个完善的实时监控系统,能够及时发现和处理系统问题,保证业务的稳定运行。
