如何调整 Apache Web 服务器的内存分配,以防止我的 EC2 Linux 实例中出现内存不足错误?

3 分钟阅读
0

我在 Amazon Elastic Compute Cloud (Amazon EC2) Linux 实例上运行的 Apache Web 服务器间歇性地没有响应。我在实例的系统日志中收到“out of memory”(内存不足)、“oom”、“oom-killer”、“failure to fork process”(分叉进程失败)或其他内存不足消息。

简短描述

默认情况下,Apache 可以同时接受 256 个连接。使用 Apache 配置中的 ServerLimit 来配置此配额。

小型实例类型(例如 t2.small)的内存仅为 2 千兆字节 (GB),无法管理 256 个同时进行的 Apache 连接。因此,当服务器流量过大时,您可能会收到以下错误之一:

  • “Out of memory”(内存不足)
  • “Oom”
  • “Oom-killer”
  • “Failure to fork process”(分叉进程失败)
  • 关于系统日志中内存不足的说明

要分析您的实例系统日志,请根据您的操作系统 (OS) 发行版查看以下日志文件:

  • 对于 Debian 和 Ubuntu,请查看 /var/log/syslog
  • 对于 Amazon Linux、CentOS 和 Red Hat Enterprise Linux (RHEL),请查看 /var/log/messages

解决方法

为避免实例出现内存错误,请为服务器接受的 Apache 和 httpd 并发连接数设置配额。使用 Apache 配置中的 MaxRequestWorkers (Apache 2.4) 参数来设置配额。对于非线程化的 Prefork 服务器,MaxRequestWorkers 表示 Apache 根据服务器请求启动的最大子进程数。

以下解决方法适用于 Web 服务器使用的默认 Prefork Apache 多处理模块 (MPM) 模型。要确认您的 MPM,请运行以下命令:

# apachectl -V | grep "MPM"

要计算要为 MaxRequestWorkers 设置的近似值,请确定您的工作负载对以下设置的使用情况:

  • 您的服务器的物理 RAM
  • 其他服务使用内存后剩余的内存
  • 占用最多内存的 Apache 进程

**注意:**最佳做法是对 MaxRequestWorkers 使用 REMAINING RAM90-100%,以平衡服务器性能和稳定性。但是,您的工作负载可能有不同的需求。

计算服务器的物理 RAM

要计算 RAM,请运行以下命令:

# free -m | grep Mem: | awk '{print $2}'

计算其他服务使用内存后剩余的内存

首先,计算除 Apache 之外的所有主要服务的内存使用量。针对每个服务运行以下命令:

# usage_mbytes=0; for usage_by_pids in `ps -C $proc_cmd -o rss | grep -v RSS`; do usage_mbytes=$(($usage_mbytes + $usage_by_pids)); done; echo $(($usage_mbytes/1024)) MB;

**注意:**在前面的命令中,请将 $proc_cmd 替换为服务名称或命令。例如,使用 mysqld 来计算 mysqld 服务的内存使用量。

计算出每个服务的内存使用量后,将这些值相加,以得到所有其他主要服务的内存使用总量。

然后,使用以下公式从服务器的物理 RAM(以兆字节 (MB) 为单位)中减去所有其他主要服务的内存使用量:

剩余内存 =(服务器的物理 RAM)-(所有其他主要服务的内存使用量)

确定使用最多内存的 Apache 进程

要确定使用最多内存的进程,请运行以下命令:

# sudo bash -c 'high_mem=0; for pid in $(ps aux | grep -E "httpd|apache2" | grep -v ^root | awk "{print \$2}"); do memory=$(pmap -d $pid | grep "writeable/private" | awk "{print \$4}" | sed "s/[^0-9]//g"); if [[ $memory -gt $high_mem ]]; then high_mem=$memory; fi; done; echo $((high_mem/1024)) MB'

记下该进程使用的内存量。

计算 MaxRequestWorkers

使用以下公式计算 MaxRequestWorkers

MaxRequestWorkers =(剩余内存 * 90/100)/(最大的 Apache 进程消耗的内存)

注意:请将剩余内存替换为其他服务使用内存后剩余的内存,将最大的 Apache 进程消耗的内存替换为最大进程使用的内存。

上述计算方法同样适用于基于 Ubuntu、Debian 和 RHEL 的系统。但是,Apache 配置路径和文件名取决于操作系统类型。根据您的操作系统设置 MaxRequestWorkers

**注意:**以下示例使用 Apache 版本 2.4 或更高版本。

Debian 和 Ubuntu

完成以下步骤:

  1. 连接到您的 Linux 实例

  2. 要在编辑器模式下打开 /etc/apache2/mods-available/mpm_prefork.conf 文件,请运行以下命令:

    # vi /etc/apache2/mods-available/mpm_prefork.conf
  3. MaxRequestWorkers 参数更改为您计算出的值。
    示例:

    <IfModule mpm_prefork_module>      StartServers            5  
        MinSpareServers         5  
        MaxSpareServers        10  
        MaxRequestWorkers    your_value  
        MaxConnectionsPerChild  0  
    </IfModule>

    **注意:**请将 your_value 替换为计算出的 MaxRequestWorkers 值。此外,请根据您的需求配置其他参数。

  4. 保存文件,然后退出该文件。

  5. 运行以下命令以执行 Apache 语法检查:

    # apachectl configtest
  6. 如果您收到 Syntax OK(语法正常)的输出,请运行以下命令重启 Apache:

    # systemctl restart apache2

Amazon Linux、CentOS 和 RHEL

完成以下步骤:

  1. 使用 SSH 登录到服务器

  2. 创建一个路径为 /etc/httpd/conf.d/mpm_prefork.conf 的文件,然后添加以下命令块:

    <IfModule mpm_prefork_module>      StartServers            5  
        MinSpareServers         5  
        MaxSpareServers        10  
        MaxRequestWorkers    your_value
        MaxConnectionsPerChild  0  
    </IfModule>

    **注意:**请将 your_value 替换为计算出的 MaxRequestWorkers 值。此外,请根据您的需求配置其他参数。

  3. 保存文件,然后退出该文件。

  4. 运行以下命令以检查 Apache 的配置语法:

    # httpd -t
  5. 如果您收到 Syntax OK(语法正常)的输出,请运行以下命令重启 Apache:

    # systemctl restart httpd

相关信息

教程: 在 Amazon Linux 2 上安装 LAMP 服务器

教程: 在 Amazon Linux 2023 上安装 LAMP 服务器

AWS 官方
AWS 官方已更新 3 个月前