如何优化 Apache Web 服务器的内存分配以防止 EC2 Linux 实例出现内存不足错误?

上次更新时间:2021 年 9 月 16 日

我的 Apache Web 服务器在 Amazon Elastic Compute Cloud(Amazon EC2)实例上运行,但存在间歇性无响应的问题。我在实例的系统日志中看到“out of memory”(内存不足)、“oom”(内存不足)、“oom-killer”(内存不足–中止)、“failure to fork process”(进程分支失败)或其他有关内存不足的消息。如何修复此问题?

简短描述

要查看系统日志以验证错误消息:

  1. 打开 Amazon EC2 控制台,然后选择 Instances(实例)。
  2. 选中该实例的复选框。
  3. 依次选择 Actions(操作)、Monitor and troubleshoot(监控和问题排查)、Get system log(获取系统日志)。

注意:如果您使用的不是新版 Amazon EC2 控制台,则依次选择 Actions(操作)、Instance Settings(实例设置)、Get System Log(获取系统日志)。

如果您建立了与该实例的终端会话,则可能会在您 Linux 实例发行版的相关位置看到堆栈跟踪。

Debian 和 Ubuntu:/var/log/syslog

Amazon Linux、CentOS 和 RHEL:/var/log/messages

使用 systemd 的系统:journalctl

解决方法

间歇性停机和收到内存不足错误的消息,可能表明实例的内存已经耗尽。

您可以对服务器接受的连接数和启动的进程数设置限制。您可以计算一个 Apache 进程的典型内存使用量,然后再将您要分配给 Apache 的总内存除以此平均使用量,从而得出限制值。

如果您运行的是 Apache 2.4,请执行以下操作:

1.    启动到该实例的终端会话。如果无法连接,则可能需要重新启动实例。

2.    在终端会话中,运行 top 命令以在实例上显示内存驻留进程列表。
按所用内存百分比降序对列表进行排序。要对基于 rpm 的实例进行排序,按 Shift+O,然后按 n
对于其他 Linux 发行版,选择适当的选项以按内存使用情况对进程进行排序。

3.    扫描为 Apache 进程返回的 %MEM 值所组成的列,并确定平均值。

4.    查找与其他 Apache 进程的 %MEM 值相比,%MEM 值异常大的一个或多个 Apache 进程。%MEM 值较大,可能说明服务器上运行的某个 Web 应用程序存在内存泄漏的问题。要缓解潜在内存泄漏的影响,请将变量 MaxRequestsPerChild 的默认值设置为 4500。

要设置此配置变量,请在 /etc/httpd/config.d 目录中创建一个新文件。在以下示例命令中,此新文件是 prefork.conf

$ sudo vim /etc/httpd/config.d/prefork.conf

MaxRequestsPerChild 变量设置为第 6 步中示例所示的值。

5.    按以下方式计算 ServerLimitMaxRequestWorkers 配置变量的值:

如果实例的 RAM 大于 4GB,则用 90% 除以 Apache 进程的平均 %MEM 值。例如,假设平均 %MEM 值为 0.8%,则用 90%(0.9)除以 0.8%(0.008)得 112.5,然后按最接近的整数向下取整,即 112。

如果实例的 RAM 小于等于 4GB,则用 80% 除以 Apache 进程的平均 %MEM 值。例如,假设平均 %MEM 值为 0.8%,用 80%(0.8)除以 0.8%(0.008),结果为 100。

注意:计算这些值的假设前提是,实例是专用 Web 服务器。如果您在该服务器上还托管了其他应用程序,则在执行计算之前应从 90% 或 80% 中减去这些应用程序使用的内存总百分比。如果除 Apache 之外,您在 RAM 等于小于 4GB 的实例上还运行了其他应用程序,则性能可能会降低。

6.    更新 prefork.conf 文件中的 MaxRequestWorkersServerLimit 配置变量,并保存更改。

例如:

IfModule mpm_prefork_module
    StartServers          10
    MinSpareServers       20
    MaxSpareServers       40
    MaxRequestWorkers     112
    ServerLimit           112
    MaxRequestsPerChild   4500
/IfModule

7.    从终端会话运行以下命令,重新启动 Web 服务器:

sudo service httpd restart

如果您运行的是 Apache 2.2,请执行以下操作:

1.    启动到该实例的终端会话。如果您无法连接,则可能需要重新启动实例。

2.    在终端会话中,运行 top 命令以在实例上显示内存驻留进程列表。
按所用内存百分比降序对列表进行排序。
要对基于 rpm 的实例进行排序,按 Shift+O,然后按 n。对于其他 Linux 发行版,选择适当的选项以按内存使用情况对进程进行排序。

3.    扫描为 Apache 进程返回的 %MEM 值所组成的列,并确定平均值。

4.    查找与其他 Apache 进程的 %MEM 值相比,%MEM 值异常大的一个或多个 Apache 进程。%MEM 值较大,可能说明服务器上运行的某个 Web 应用程序存在内存泄漏的问题。要缓解潜在内存泄漏的影响,请将配置变量 MaxConnectionsPerChild 的默认值从 4000 更改为 1000。

此更改可以在您识别和纠正内存泄漏的来源时部分缓解此问题。如果您怀疑存在内存泄漏,则使用新的配置值更新实例上的 httpd.conf 文件,保存更改,然后跳到第 7 步。

5.    按以下方式计算 ServerLimitMaxClients 配置变量的值:

如果实例的 RAM 大于 4GB,则用 90% 除以 Apache 进程的平均 %MEM 值。例如,假设平均 %MEM 值为 0.8%,则用 90%(0.9)除以 0.8%(0.008)得 112.5,然后按最接近的整数向下取整,即 112。

如果实例的内存等于小于 4GB,则用 80% 除以 Apache 进程的平均 %MEM 值。例如,假设平均 %MEM 值为 0.8%,用 80%(0.8)除以 0.8%(0.008),结果为 100。

注意:计算这些值的假设前提是,实例是专用 Web 服务器。如果您在该服务器上还托管了其他应用程序,则在执行计算之前应从 90% 或 80% 中减去这些应用程序使用的内存总百分比。如果除 Apache 之外,您在 RAM 等于小于 4GB 的实例上还运行了其他应用程序,则性能可能会降低。

6.    在 httpd.conf 文件中使用新值更新实例的 MaxClientsServerLimit 配置变量,然后保存更改。

例如:

MaxClients = 112 
ServerLimit = 112

7.    从终端会话运行以下命令,重新启动 Web 服务器:

apachectl graceful

这篇文章对您有帮助吗?


您是否需要账单或技术支持?