我正在运行 Apache 网络服务器,想稍微改进一下处理 OOM 情况的方式。
我知道 OOM 分数,并且已经对此做了一些自定义,因此当发生不良事件时,Linux 会终止正确的进程。但这还不够。
问题是,有时发生 OOM 时,服务器会过载,然后崩溃,必须重新启动。我想在不完全重新启动服务器的情况下处理这个问题。所以我需要以某种方式在 OOM killer 调用上“挂接”一个脚本,该脚本将终止所有 apache(及其 CGI)进程,从而释放内存并重新启动它(Apache)。
我知道这会起作用,因为如果发生 OOM 并且我足够快地登录到服务器并手动终止 Apache,那么一切都会正常。
仅供参考,我现在正在运行近百个网络服务器,这就是我寻找全自动解决方案的原因。
当然,一种可能的解决方案是使用一些可以解析系统日志并以这种方式检测 OOM 的看门狗 - 我已经有了类似的东西,它通过电子邮件通知 OOM 终止。这种方法可以解决某些情况,但如果 OOM 确实很严重,服务器超载太多,我的脚本甚至无法启动(它由 cron 运行)。可以使用 inotify 监视系统日志或将系统日志直接(即通过 fifo)传输到脚本来改进它。
但我仍然想知道 - 有没有办法将脚本直接“挂钩”到 OOM 杀手?所以我会将类似的东西放在某个 /etc/.. 文件中:
oom_action="sh /path/to/my/script.sh kill"
或者根本就不可能这样做?
我正在使用 Centos 6、Apache 2.2 和 PHP 作为 FastCGI。
答案1
为什么不监视 apache 进程并将它们的oom_adj
值设置为 15,以确保它们将在 OOM 时首先终止?这里以下是关于此设置的一些说明。
根据您的配置,您可以修改 apache 启动脚本或设置一个简单的 cron 任务来执行此操作。
您还可以定期查看命令的输出dmesg | grep -i oom
。如果有任何行,则 OOM killer 自上次启动服务器以来杀死了某人。然后您可以使用以下命令清除缓冲区dmesg --clear
答案2
我知道现在有很多可怕的 PHP 应用程序,但某物您可以在 Apache/FastCGI/PHP 方面做些什么?Apache 不断出现 OOMing 的情况您不应该经常遇到。
尝试降低 Apache 进程和 FastCGI 处理程序的最大数量,并查看当前 php.ini 设置是否对于每个脚本的最大内存来说太高。
此外,完全可以ulimit
与 Apache 一起使用并限制进程可以使用的内存数量。这可以在服务器几乎崩溃之前为您提供帮助。
OOM 是最后手段,所有可能导致 OOM 的因素都应进行检查。
答案3
由于我没有找到更好的解决方案,我已经实现了看门狗来读取内核系统日志消息(通过 fifo):
/etc/rsyslog.d:
(...)
kern.err |/path/to/fifo
并搜索其中的 OOM-killer 活动:
while read /path/to/fifo; do (..)
当 OOM-killer 大量出现时(我真的只需要检查紧急情况),我会杀死(然后启动)Apache。
答案4
我认为最好将你的进程放在 cgroup 内存子集中,并release_agent
在内存不足时使用它来调用外部脚本
notify_on_release
contains a Boolean value, 1 or 0, that either enables or disables the execution of the release agent. If the notify_on_release is enabled, the kernel executes the contents of the release_agent file when a cgroup no longer contains any tasks (that is, the cgroup's tasks file contained some PIDs and those PIDs were removed, leaving the file empty). A path to the empty cgroup is provided as an argument to the release agent.
release_agent (present in the root cgroup only)
contains a command to be executed when a “notify on release” is triggered. Once a cgroup is emptied of all processes, and the notify_on_release flag is enabled, the kernel runs the command in the release_agent file and supplies it with a relative path (relative to the root cgroup) to the emptied cgroup as an argument. The release agent can be used, for example, to automatically remove empty cgroups
使用 cgroup,你可以控制进程可以使用的资源量,并且不会使服务器过载
Using cgroup you can control the server resources