私はApacheWebサーバーを実行しており、OOM状況の処理方法を少し改善したいと思います。
私はOOMスコアに精通しており、すでにいくつかのカスタマイズを行っているため、何か問題が発生した場合、Linuxは正しいプロセスを強制終了します。しかし、それだけでは十分ではありません。
問題は、OOMが発生するとサーバーが過負荷になり、その後クラッシュして再起動する必要がある場合があることです。サーバーを完全に再起動せずに処理したいと思います。したがって、OOM killerの呼び出しでスクリプトを「フック」して、すべてのApache(およびそのCGI)プロセスを強制終了し、メモリを解放して再起動する必要があります(Apache)。
OOMが発生し、サーバーにログインしてApacheを手動で強制終了するのに十分な速度があれば、すべて問題ないので、これが機能することはわかっています。
参考までに、私は現在、これらのWebサーバーを100近く実行しています。そのため、完全に自動化されたソリューションを探しています。
もちろん、考えられる解決策の1つは、syslogを解析し、この方法でOOMを検出するウォッチドッグを使用することです。私はすでにそのようなものを持っており、電子メールでOOMの強制終了について通知します。このアプローチはいくつかの状況を解決できますが、OOMが本当に悪い場合、サーバーが過負荷になりすぎて、スクリプトが起動しません(cronによって実行されます)。これは、inotifyを使用してsyslogを監視するか、syslogをスクリプトに直接(つまり、fifoによって)パイプすることで改善できます。
しかし、それでも疑問に思っています。スクリプトをOOM killerに直接「フック」する方法はありませんか?だから私はそのようなものをいくつかの/ etc/..ファイルに入れます:
oom_action="sh /path/to/my/script.sh kill"
それとも、そのようにすることは単に不可能ですか?
FastCGIとしてCentos6、Apache 2.2、PHP)を使用しています。
より良い解決策が見つからなかったので、カーネルのsyslogメッセージを読み取るためのウォッチドッグを実装しました(fifo経由):
/etc/rsyslog.d:
_(...)
kern.err |/path/to/fifo
_
oOM-killerアクティビティを検索します。
while read /path/to/fifo; do (..)
そして、OOM-killerが大量にスポーンしたとき(私は本当に緊急事態だけをチェックする必要があります)、Apacheを殺します(そして起動します)。
Apacheプロセスを監視し、そのoom_adj
値を15に設定して、それらがOOMで最初に終了することを確認してみませんか? ここ この設定に関するいくつかの指示です。
構成に応じて、Apache開始スクリプトを変更するか、それを行うための単純なcronタスクを設定できます。
コマンドdmesg | grep -i oom
の出力を定期的に監視することもできます。行がある場合は、サーバーが前回起動されてからOOMkillerが誰かを殺しました。その後、dmesg --clear
でバッファをクリアできます。
恐ろしいPHPアプリケーションがたくさんありますが、そこにはありません何か Apache/FastCGI/PHP側でできることはわかっています?Apacheの絶え間ないOOMingは、頻繁に遭遇するものではありません。
ApacheプロセスとFastCGIハンドラーの最大数を減らして、現在のphp.ini設定がスクリプトあたりの最大メモリに対して高すぎるかどうかを確認してください。
また、Apacheでulimit
を使用して、プロセスが使用できるメモリの数を制限することも完全に可能です。これは、サーバーがスパイラルして死ぬ前に役立ちます。
OOMは非常に最後の手段であり、それにつながる可能性のあるすべてのものを検査する必要があります。
プロセスをcgroupメモリサブセットに配置し、release_agent
を使用して、メモリ不足が発生したときに外部スクリプトを呼び出す方がよいと思います。
notify_on_release
contains a Boolean value, 1 or 0, that either enables or disables the execution of the release agent. If the notify_on_release is enabled, the kernel executes the contents of the release_agent file when a cgroup no longer contains any tasks (that is, the cgroup's tasks file contained some PIDs and those PIDs were removed, leaving the file empty). A path to the empty cgroup is provided as an argument to the release agent.
release_agent (present in the root cgroup only)
contains a command to be executed when a “notify on release” is triggered. Once a cgroup is emptied of all processes, and the notify_on_release flag is enabled, the kernel runs the command in the release_agent file and supplies it with a relative path (relative to the root cgroup) to the emptied cgroup as an argument. The release agent can be used, for example, to automatically remove empty cgroups
Cgroupを使用すると、処理できるリソースの量を制御でき、サーバーに大きな過負荷をかけないようにすることができます
Using cgroup you can control the server resources