Amazon Elastic Compute Cloud (Amazon EC2) Linux インスタンスで実行中の Apache ウェブサーバーが応答しない現象が、断続的に発生します。インスタンスのシステムログには、「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 がサーバーリクエストに対して起動する子プロセスの最大数を表します。
次の解決策は、ウェブサーバーが使用するデフォルトの Prefork Apache マルチプロセッシングモジュール (MPM) モデルを対象としています。MPM を確認するには、次のコマンドを実行します。
# apachectl -V | grep "MPM"
MaxRequestWorkers に設定するおおよその値を計算するために、ワークロードが次の設定をどの程度使用しているかを判断します。
- サーバーの物理 RAM
- 他のサービスがメモリを使用した後に残るメモリ
- 最もメモリを消費する Apache プロセス
注: サーバーのパフォーマンスと安定性のバランスを取るには、MaxRequestWorkers の REMAINING RAM 値を 90 ~ 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 単位)。
** Remaining memory (残りのメモリ) = (サーバーの物理 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 プロセスが消費するメモリ)
注: 実際の値でそれぞれ、Remaining Memory を他のサービスがメモリを使用した後に残るメモリに置き換え、Memory consumed by largest Apache process を使用率が最大であるプロセスが消費するメモリに置き換えます。
上記の計算は、Ubuntu、Debian、RHEL ベースのシステムでも同様です。ただし、Apache の設定パスとファイル名は OS の種類によって異なります。お使いの OS に応じて MaxRequestWorkers を設定します。
注: 次の例では、Apache バージョン 2.4 以降を使用します。
Debian と Ubuntu
次の手順を実行します。
-
Linux インスタンスに接続します。
-
ファイル /etc/apache2/mods-available/mpm_prefork.conf をエディタモードで開くには、次のコマンドを実行します。
# vi /etc/apache2/mods-available/mpm_prefork.conf
-
MaxRequestWorkers パラメータを、計算した値に変更します。
例:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers your_value
MaxConnectionsPerChild 0
</IfModule>
注: your_value は、計算した MaxRequestWorkers の値に置き換えます。要件に合わせて、他のパラメータも設定してください。
-
ファイルを保存してから閉じます。
-
次のコマンドを実行して Apache の構文チェックを実行します。
# apachectl configtest
-
Syntax OK の出力が表示された場合は、次のコマンドを実行して Apache を再起動します。
# systemctl restart apache2
Amazon Linux、CentOS、RHEL
次の手順を実行します。
-
SSH を使用してサーバーにログインします。
-
パス /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 の値に置き換えます。要件に合わせて、他のパラメータも設定してください。
-
ファイルを保存してから閉じます。
-
次のコマンドを実行して Apache の設定構文を確認します。
# httpd -t
-
Syntax OK の出力が表示された場合は、次のコマンドを実行して Apache を再起動します。
# systemctl restart httpd
関連情報
チュートリアル: Amazon Linux 2 に LAMP サーバーをインストールする
チュートリアル: Amazon Linux 2023 に LAMP サーバーをインストールする