一行脚本来检查和反应内存使用情况

我想有一行shell / bash,沿着这些线做一些事情:

test "`free | grep | awk | whatever` -gt 80" && any_command 

如果将整个系统使用的RAM总数与硬编码数(在我的情况下是80)进行比较, 只要ram高于给定的百分比, any_command执行test

  • 确切的字节/兆字节,而不是百分比是好的
  • 这应该在典型的Ubuntu 14.04上工作
  • 打算用作cron作业
  • 奖励:单线程做同样的事情,但检查公羊的具体过程

更新

关于这是monit / bluepill / god这样的问题是如何解决的问题有答案。 我同意100%,你应该很可能遵循这些答案的build议。 但是,这个问题具体是关于我所描述的确切路线,无论出于什么原因,假设所有可能涉及的警告和问题。

怎么样:

 [ $(free -m| grep Mem | awk '{ print int($3/$2*100) }') -gt "80" ] && echo "greater " || echo "lesser" 

对于过程消耗,这里是解决scheme的一个可能的部分:

 for p in $(pgrep bash); do total=$(($total + $(awk '/VmSize/ { print $2 }' /proc/$p/status))); done ; echo "Total memory usage: $total kb" ; unset total 

将这两者结合起来作为练习给读者。

不要重新发明轮子:)

Monit工具是专门用来处理这种情况的。 这是很好的文档 ,并在这里有很多的例子在ServerFault 。

  check system kale.GreenLeaf.com if loadavg (5min) > 16 for 15 cycles then alert if memory usage > 92% then alert if swap usage > 10% then alert 

或者一个过程:

 check process cups with pidfile "/var/run/cupsd.pid" start program = "/sbin/service cups start" stop program = "/sbin/service cups stop" if 10 restarts within 11 cycles then timeout if total memory > 1000.0 MB for 5 cycles then alert if total memory > 2000.0 MB for 5 cycles then restart if cpu usage > 95% for 11 cycles then restart 

警报或启动/停止/重新启动操作,而不是一个EXEC:

EXEC可以用来执行任意程序并发送警报。 如果您select此操作,则必须声明要执行的程序,并且如果程序需要参数,则必须将程序及其参数括在引用的string中。 您可以select指定执行的程序在开始时应该切换到的uid和gid …

 if total memory > 2000.0 MB for 5 cycles then exec "/sbin/service sidekiq restart" 

你究竟想要完成什么? 你可能试图做错了。

 [ $(free | perl -nE 'if (/Mem/) { (undef,$total,$used) = split; say int(100*$used/$total) }') -gt 80 ] && echo foo 

但是请注意,无论你试图完成什么, 几乎肯定是无用的 (甚至可能是有害的)。 没有“正在使用的百分比RAM”这样的东西。 是的, free会告诉你有多less内存是“免费”的,但这可能并不意味着你认为它的意思(这个领域会更好地命名为“浪费”或“你应该从来没有买过的内存量”)。

例如,内核不会“加载”内存中的程序,而是映射它们,因此,几百MB的示例程序就可以运行,而不pipe只有12KB。 而且所有被访问的文件都将被caching在同一个内存中(称为页面caching) – 过去运行的程序(如果它再次运行,它的文件被caching)或者被读取/写入的数据文件之间没有区别过去(所以如果他们再次访问,他们会更快)

所以,如果你的磁盘比内存更多(通常情况下是这样),那么开机后你的“自由”(即“浪费”)内存将快速收敛到接近100%(实际上更像是80-95%,因为内核会试图保持有些是免费的,所以有内存压力时可以快速访问它)。 这是正常的,实际上是想要的,因为它会大大加快你对磁盘的访问速度(最好的情况下),或者如果没有再次访问相同的文件(最坏的情况),就像“空闲内存”一样好。

所以你实际上想要避免内存“自由”(内存密集型程序不时发生)。

编辑1 :另外,上面的结果只是可能(和完全不同)的答案,因为这样的问题是未定义的。 例如,你可以使用“Mem used-cached”(当使用磁盘高速caching时显示多less内存),而不是“Mem used”,你可以使用“15%”来代替“80%使用”),并可能更准确 – 取决于你想要完成什么

至于进程内存使用情况,同样的事情 – 有太多方法可以说明一个进程使用多less内存。 程序需要的数量( ps输出中的VSZ)。 或者当前在RAM中的数量(RSS列)。 那么当有多个共享代码的情况下(例如,如果你有100个apache进程,每个50MB的RSS进程,他们不使用100 * 50 = 5000MB的RAM,但更像200MB)等等。当你确切地知道什么你想要的,只有那么你可以继续计算它(只是VSZ,或只是RSS,或RSS共享,或RSS共享/进程数量共享等)

还要注意,这类问题更多的是关于superuser.com的主题

编辑2:至于你的评论,你试图避免内存泄漏是一些过程。 检查可用内存肯定是错误的,因为它会给误报。 你应该限制你的进程,以防止内存泄漏导致系统的其他部分closures(请参阅bash中的help ulimit )。 这个进程可能会处理(好的)或死的时候,它不能得到所需的内存量,所以你可以重新启动它(通过监视,监督,运行或类似的)

编辑3:另外(或作为替代,但更好的另外)设置进程限制,你可以使用这样的事情来重新启动进程时,RSS增长太大。

 [ $(awk '/^VmRSS/ { print $2}' /proc/$PID/status) -gt 200 ] && echo killmeplease 

而不是$PID你当然会使用你的PID(例如从PID=$(cat /var/run/something.pid)PID=$(pidof somedaemon)PID=$(pidof somedaemon)

但是请注意,你可能最好使用VmSize (或VmPeak )而不是( VmRSS ),否则你的进程如果进入交换可能会使系统停机(所以VmSize会很大,而VmRSS会很小)