こんにちは、OSSよろず相談室の神崎です。
今回は、Apache のエラー AH00288 と logrotate の関係性に焦点を当てて、原因や対策を解説していきます。
AH00288: scoreboard is full, not at MaxRequestWorkers
このメッセージが、logrotate 実行時の Apache HTTP Server のエラーログに出力されることがあります。
以下の流れでこのエラーを深堀りしていきます。
AH00288 メッセージについて
対象のMPM
まず、このエラーは MPM が worker MPMの場合に出力されます。event MPMの場合は、AH003490 エラーが出力されます。
エラーメッセージの解説
次にエラーメッセージに着目します。
scoreboard is full はスコアボードに登録できるスレッドの枠が限界に達したことを意味します。
※スコアボードとは、スレッドの接続数と各スレッドの処理状態をリアルタイムに記録・共有するためのメモリ構造です。
not at MaxRequestWorkers は MaxRequestWorkers に達していないことを意味します。
MaxRequestWorkers は、Apache が同時に処理できるリクエストの最大数です。
スコアボードのスレッドの接続数と MaxRequestWorkers が対応しています。
つまり、Apache が同時に処理できるリクエストの最大ではないのにも関わらず、スコアボードの接続数が埋まっているというエラーになります。
原因の一つとしては終了した古いプロセスやスレッドがスコアボード上に残ってしまっているということが考えられます。
logrotate とAH00248 エラーについて
logrotate 時になぜ AH00248 エラーが発生するのかについて解説していきます。
logrotate とは Linux がサポートするログローテーションのツールです。logrotate の設定内容にもよりますが、ログローテーションの際に Apache の再起動させることが一般的です。通常は、サービスの停止を最小限にするために、graceful restart をプロセス数の少ない深夜に実行することで運用されています。
logrotate と graceful restart
logrotate が実行されると、graceful restart が行われます。
graceful restart とは、Apache サーバの再起動時に、プロセスが行っている現在の処理を完了してから終了し、新しいログファイルを再オープンする動作のことを指します。これはプロセス単位で行われるため、プロセス内でのスレッドがすべての処理が完了後にそのプロセスが再起動します。
この処理の目的は、サーバが新しいリクエストを受け付けることができない時間を最小限に抑えるとともに、設定ファイルに記載されたパラメータを尊重することです。
しかし、上記で述べたように稼働中の古いプロセスはリクエストが終了するまでプロセスとスレッドは graceful restart 後のリクエストを受け付けることができない状態です。それに加えて、graceful restart 後に確保するアイドルスレッドや新しく受け付けたリクエストでスコアボードがうまってしまい、AH00288 エラーが出力されます。
※古いプロセス内のスレッドは新しいリクエストを受け付けない状態なので MaxRequestWorkers と処理できるリクエスト数が一致しない
Apacheのドキュメントにてこのエラーについての説明があります。
※event MPM の説明ですが、worker MPM においても同様の現象だと考えます。
※worker MPM には event MPM の “From 2.4.24 onward,” に記載の機能改善は行われていません。
Apache MPM event / Graceful process termination and Scoreboard usage
基本的には、古いプロセスは終了し次第プロセス内の全スレッドが解放されていくので、処理自体に問題はありません。
しかし、高負荷のシステムであればリクエストが処理しきれなくなるため、問題になる可能性があります。
AH00248 エラーの対策
解決策としては、2つの方法が考えられます。
- MPM のパラメータの調整
- rotatelogs の使用
MPM のパラメータの調整
エラーを出力されないように MPM のパラメータを調整します。
MPM のパラメータは、httpd.conf の <IfModule mpm_worker_module> タグ内で以下のように設定することができます。
<ifmodule mpm_worker_module>
ServerLimit 16 //子プロセスの最大数
StartServers 2 //起動時に子プロセスの数(リクエスト処理用)
MaxRequestWorkers 150 //最大リクエスト処理数
MinSpareThreads 25 //アイドルスレッド数の最小数
MaxSpareThreads 75 //アイドルスレッド数の最大数
ThreadsPerChild 25 //子プロセスが生成するスレッド数
</ifmodule>
Apacheドキュメント / Apache MPM worker より設定の典型例を抜粋
graceful restart によって、リクエスト処理中の古い子プロセスのスレッドが解放されないため、スコアボードの上限 (MaxRequestWorkers や ServerLimit) を上げることや起動直後のプロセス数 (StartServers) を制限することにより、スコアボードが埋まるのを対策することができます。
※graceful restart の仕様として、スレッドが一つでも稼働中だと子プロセスは再起動されないため、ServerLimit を調整が有効です。
※パラメータを変更した場合、通常時の運用に影響が出る可能性があります。
1つのパラメータを変更すると、他のパラメータの調整が必要になる場合があります。以下を目安に調整してください。
ServerLimit × ThreadsPerChild >= MaxRequestWorkers
MinSpareThreads + 想定最大アクティブスレッド数 < MaxRequestWorkers
MaxSpareThreads + 想定最小アクティブスレッド数 < MaxRequestWorkers
rotatelogs の使用
logrotate では graceful restart が実行されてしまうので、rotatelogs を代わりに実行するという方法があります。
rotatelogs は Apache がサポートするログローテーションツールで Apache のアクセスログまたはエラーログを
graceful restart の必要なくローテーションが可能です。
graceful restart しないのため AH00288 エラーはログローテーションの際には発生しませんが、設定の反映等のため定期的な再起動を必要とします。
参考文献
類似のエラーである AH03490 についてより詳細に解説していますので、ぜひご覧ください
サポートエンジニアの現場から!Apacheエラー「AH03490」を徹底解説
StartServers、ServerLimit、ThreadsPerChild、MaxSpareThread等、各MPMの値のパラメータの説明は以下を参照してください。
Apacheドキュメント / Apache MPM Common Directives
logrotate についての基本知識です。
知っておくとちょっと便利!logrotate の仕組みについて1
Red Hat社の公式ドキュメントで logrotate と rotatelogs について説明があります。(Red Hat社の有料ポータルログインIDが必要です)
logrotate と rotatelogs を使用して Apache HTTPD のログをローテーションするにはどうすればよいですか?