同じような過負荷トラブルが起きたときに、 「何を変えたらハングアップを回避できたか」をすぐ参照できるように、 実際に効いた対策だけを記録しておきます。
再現実験では、 高負荷時にワーカー上限到達とメモリ圧迫が連鎖して サーバー全体が応答不能になることを確認しました。
対策方針
狙いはシンプルです。
- 負荷時に処理能力を超えた分は早めに失敗させる
- その代わり、OS と管理経路(SSH)は生かし続ける
つまり、 「ハングアップして全停止」ではなく 「過負荷時に限定的に遅延・タイムアウトする」状態に寄せます。
まず試したが効果が薄かった調整
初期対応として PHP / PHP-FPM 側の値を中心に変更しましたが、 根本的な改善は見られませんでした。
# /etc/php.ini
memory_limit = 128M -> 2048M
# /etc/php-fpm.d/www.conf
pm.max_children = 50 -> 200
pm.start_servers = 10 -> 5
pm.min_spare_servers = 10 -> 5
pm.max_spare_servers = 20 -> 30
# /etc/httpd/conf/httpd.conf
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
pm.max_children を増やす方向は、
短期的には捌けるリクエストが増えても、
最終的にメモリ消費を押し上げる副作用がありました。
効果があった対策: Apache の同時処理上限を明確化
次に Apache 側で、
同時処理上限(MaxRequestWorkers)を絞る方向へ変更しました。
# /etc/httpd/conf/httpd.conf
<IfModule mpm_worker_module>
ServerLimit 5
StartServers 1
MaxRequestWorkers 50 → 20
MinSpareThreads 10
MaxSpareThreads 20
ThreadsPerChild 10
MaxConnectionsPerChild 4000
</IfModule>
変更意図は、 「処理可能数の上限を明示し、リソースを食い潰す前に頭打ちにする」ことです。
変更後の挙動
同条件で負荷をかけたところ、 次のような挙動に変化しました。
- 高負荷時にクライアント側では
ERR_TIMED_OUTが発生 - 一方でサーバー自体はハングアップしない
- 負荷が下がるとサービスが自律的に復帰
- SSH での保守操作が継続可能
これは、 過負荷を「全面停止」ではなく「劣化運転」に変換できた状態です。
メモ
- スペック増強だけでは DoS 的負荷に対する耐性は上がりませんでした
- 受け入れる同時処理数の上限設計が最優先だと分かりました
- 低優先度サーバーほど「甘い設定」を放置しやすく、後で痛手になると実感しました
今後の運用
最終的に、 本番インスタンスタイプで再試験した値を採用し、 段階的にプロダクションへ反映しました。
以後は以下を継続監視します。
- Apache の
MaxRequestWorkers到達頻度 - PHP-FPM の
pm.max_children到達頻度 - 応答遅延とタイムアウト率
- 特定 IP / AS へのアクセス偏り
このマシンは運用予算が限られているため、 WAF や上位プロキシの導入には頼らず、Apache / PHP-FPM のパラメータチューニングを継続して耐性を高めていきます。