内存严重不足时自动终止/重启进程

内存严重不足时自动终止/重启进程

我有一台 Debian Wheezy VPS 机器,正在生产环境中运行几个 Django 应用程序。理想情况下,我会尝试通过优化应用程序、添加更多 RAM 或使用 Swap 进行扩充来解决我当前的内存占用问题。但问题是,我怀疑优化 Django 应用程序(堆栈是开源且强大的)是否能带来多少内存优化,而且添加 RAM 对我来说是一个成本限制(这是一个远程 VPS),而且主机不提供使用 Swap 的选项!

因此,与此同时(当我等待获得更多资源来提供更多 RAM 时),我希望缓解服务器内存耗尽的情况,这样我只需要请求重新启动 VPS(因为,在那时,我甚至无法通过 SSH 进入盒子!)。

因此,我希望解决方案能够检测某个进程(或一般来说,总系统内存使用量)何时超过某个临界量(就目前而言,例如可用 RAM 下降到 10%) - 我注意到这种情况发生在 VPS 长时间启动之后,以及当一些繁重的应用程序的流量突然很大时(大多数只是暂存应用程序)。

因此,我希望能够终止/重新启动有问题的进程(最有可能是 Apache)。在这些情况下,哪种解决方案在手动执行时可以恢复正常的内存使用水平 - 这是否暗示一个或多个 Django 应用程序可能存在内存泄漏?


简单来说:

  1. 监控整体系统 RAM 使用情况
  2. 当可用 RAM 低于给定的临界阈值(例如低于 10%)时,终止/重新启动有问题的进程 - 或者更简单的是,如果我们从我当前的日志分析(使用 linux-dash)中假设 Apache 通常是罪魁祸首,那么就终止/重新启动它。
  3. 冲洗并重复...

答案1

Linux 内核内置了所谓的 OOM Killer。它是“内存不足杀手”。因此,当您的机器耗尽其 RAM 和交换空间时,内核将开始杀死一些东西以使服务器可访问。

您可以调整进程的优先级,以确定进程被终止的“可能性”。更多信息请阅读此链接请参阅“配置 OOM Killer”部分。

基本上,您可以在 /proc/*/oom_adj 文件中调整可能性。例如,提高终止任何当前正在运行的 apache 实例的可能性?

pgrep apache2 |sudo xargs -I %PID sh -c'echo 10 > /proc/%PID/oom_adj'

或者降低 SSH 被杀死的可能性:

pgrep sshd |sudo xargs -I %PID sh -c'echo -17 > /proc/%PID/oom_adj'

另外,我建议完全禁用出现此问题的服务器上的交换,因为交换速度太慢,可能会导致服务器陷入虚拟停滞状态,即使仍有交换空间,从而永远不会触发 OOM 杀手。

答案2

如果这些应用程序在服务器内运行apache2,则可以调整服务器。考虑:

  • 限制 MaxRequestWorkers(这限制了使用内存的工作者数量)。
  • 限制 MaxConnectionsPerChild(这将回收服务器,使它们不会消耗太多内存。如果应用程序泄漏内存,这将很有用。

如果您的进程正在泄漏内存,您可以使用/etc/security/limits.conf来限制服务器可以包含的内存量。这将防止服务器变得太大。使用 命令可以临时实现相同的效果ulimit。最好使用ulimit来发现合适的大小,然后在limits.conf文件中设置这些值。如果您的服务器支持它,请将文件放入/etc/security/limits.d而不是编辑/etc/security/limits.conf

答案3

首先,我想说重启不是解决问题的办法,更好的方法是找到有问题的进程以及它为什么消耗大量内存。如上所述,Linux 已经有 OOM 机制来查找有问题的进程并终止它以释放内存压力

另一种方法是使用 Kdump 来查找,配置此参数 vm.panic_on_oom = 1(/etc/sysctl.conf),当系统内存不足时,这将生成 vmcore。您可以在此处找到有关它的更多信息

http://people.redhat.com/anderson/crash_whitepaper/

limits.conf 也有很多限制,更好的解决方案是使用 cgroups 来限制每个进程的内存使用率

因此,在 /etc/cgconfig.conf 中,您可以像这样定义控制组(这里我限制我的应用程序仅使用 256MB 内存)

    group test {
                 memory {
                         memory.limit_in_bytes = 256m;
                 }
          }

然后在 /etc/cgrules.conf 中我可以定义你的应用程序利用率(在你的情况下 django 不能超过 256)

    *:django        memory          test/

有关 cgroup 的更多信息,可以参考

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sec-memory.html

但重新启动应用程序的想法似乎不太好。

相关内容