Hatena::ブログ(Diary)

(ひ)メモ このページをアンテナに追加 RSSフィード

2014-05-19 (Mon)

Apacheのmod_statusの各状態はどういう意味か?

Apacheのmod_statusを使えば各プロセスの状態を知ることができます。CloudForecastやCacti等でそれを元に視覚化している人も多いと思います。

mod_statusで確認できる状態には以下の11種類があるのですが、

状態名mod_stautsでの記号説明
SERVER_DEAD 0.Open slot with no current process
SERVER_STARTING 1SServer Starting up
SERVER_READY 2_Waiting for connection (or accept() lock)
SERVER_BUSY_READ 3RReading a client request
SERVER_BUSY_WRITE 4WProcessing a client request
SERVER_BUSY_KEEPALIVE5KWaiting for more requests via keepalive
SERVER_BUSY_LOG 6LLogging the request
SERVER_BUSY_DNS 7DLooking up a hostname
SERVER_CLOSING 8CClosing the connection
SERVER_GRACEFUL 9Gserver is gracefully finishing request
SERVER_IDLE_KILL 10IServer is cleaning up idle children

年に3回ぐらい「これって具体的にどういう状態なんですか?」と聞かれてテケトーに答えてたので、httpdが一生のうちどういう状態を変遷するのかと、いくつかの状態についてはソースも読みながら確認してみたのでそのメモです。

httpdの一生

Apache 2.2.27で、prefork MPMでのhttpdの一生はこんな感じでした。

  • 起動
    • DEAD -> READY
    • READY -> READY
  • リクエスト/レスポンス処理 (非 keepalive)
    • READY -> BUSY_READ
    • BUSY_READ -> BUSY_READ
    • BUSY_READ -> BUSY_WRITE
    • BUSY_WRITE -> BUSY_LOG
    • BUSY_LOG -> CLOSING
    • CLOSING -> READY
  • リクエスト/レスポンス処理 (keepalive)
    • READY -> BUSY_READ
    • BUSY_READ -> BUSY_READ
    • BUSY_READ -> BUSY_WRITE
    • BUSY_WRITE -> BUSY_LOG
    • BUSY_LOG -> BUSY_KEEPALIVE
    • BUSY_KEEPALIVE -> CLOSING
    • CLOSING -> READY

まずはDEADから始まり、もろもろ初期化を済ませると READY に遷移し、続いて生きてる限り回るループの中で(再度)READY に遷移し accept(2) してリクエストを待ちます。

リクエストが着弾してaccept(2)が抜けると、ap_read_requestによりHTTPリクエストを処理します。このap_read_requestの前にBUSY_READに遷移し、ap_read_requestが終わるとBUSY_WRITEに遷移します。

ここで留意すべきは、HTTPリクエスト処理を終えた時点でBUSY_WRITEに遷移するという点です。

低速な回線のクライアントへのレスポンスの送信の場合にBUSY_WRITE状態で滞留するのはもちろんですが、reverse proxy先のバックエンドサーバーの処理が遅い場合もBUSY_WRITEで滞留します

つまりBUSY_WRITEだけでは回線起因でレスポンス送信に時間がかかっているのか、バックエンドの処理が詰まっているのか判別できません。

バックエンドの処理が詰まっているかどうかは、その処理時間をバックエンドサーバーのログやレスポンスヘッダに入れる(で、フロントのApacheのアクセスログで記録してクライアントへのレスポンスからは当該ヘッダを消す)ようにしておけばよいと思います。

さて、無事にレスポンスを返し終えると、BUSY_LOGに遷移しap_run_log_transactionでログの記憶を行います。ちなみに、異常系で終了する場合も同じくBUSY_LOGに遷移してログを書き出します。

あとはCLOSING→READYと遷移し最初に戻ります。HTTP keepaliveが有効の場合は、BUSY_KEEPALIVE→CLOSING→READYという遷移になります。


ちなみにですが、少なくとも今回確認した Apache 2.2.27, prefork MPM, Linuxでは、

  • BUSY_DNS
  • IDLE_KILL

は使われていないようでした。

2003 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 12 |
2012 | 01 | 02 | 03 | 06 | 08 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 |
2015 | 01 | 02 | 07 | 10 |
2016 | 01 | 05 | 10 | 12 |
2017 | 07 |
2018 | 05 |