我的 Apache Web 服务器在 Amazon Elastic Compute Cloud(Amazon EC2)Linux 实例上运行,但存在间歇性无响应的问题。我在实例的系统日志中看到“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. 按以下方式计算 ServerLimit 和 MaxRequestWorkers 配置变量的值:
如果实例的 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 文件中的 MaxRequestWorkers 和 ServerLimit 配置变量,并保存更改。
例如:
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. 按以下方式计算 ServerLimit 和 MaxClients 配置变量的值:
如果实例的 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 文件中使用新值更新实例的 MaxClients 和 ServerLimit 配置变量,然后保存更改。
例如:
MaxClients = 112
ServerLimit = 112
7. 从终端会话运行以下命令,重新启动 Web 服务器:
apachectl graceful
相关信息
教程:使用 Amazon Linux AMI 安装 LAMP Web 服务器