ProxyPass には retry=?? を指定しておく

Apache でリバースプロキシを使い,フロントサーバからアプリケーションサーバにアクセスするようにすることも多いかとおもいます。このとき,アプリケーションサーバを落とすと,フロント(プロキシサーバ)がブラウザに 503 Service Temporary Unavailable を返します。そこで,メンテナンスのときはアプリケーションサーバを落としておき,フロントの 503 ページに「メンテナンス中です」と出すようにしています。

ところが,メンテナンス終了時にアプリケーションサーバを立ち上げても,しばらくは「メンテナンス中」と表示されてしまい困っていました。[http://httpd.apache.org/docs/2.2/en/mod/core.html#errordocument:title=ErrorDocument] 時のヘッダを見てみると,Cache-Control 等が設定されていません。だからブラウザがキャッシュしてしまっているのかな,と [http://httpd.apache.org/docs/2.2/en/mod/mod_headers.html#header:title=Header] ディレクティブを使って((<meta> タグでもいいと思いますが)) Cache-Control ヘッダ等を追加してみたのですが,やはりメンテナンス中のままです。


ひょっとして [http://httpd.apache.org/docs/2.2/en/mod/mod_proxy.html:title=mod_proxy] って,接続先が落ちていると,しばらくその状態をキャッシュしてしまうんじゃないだろうか。と思って調べてみたら,やはりそのとおりでした。

As of Apache 2.1, the ability to use pooled connections to a backend server is available. Using the key=value parameters it is possible to tune this connection pooling.

...... snip ......

Parameter Default Description
retry 60 Connection pool worker retry timeout in seconds. If the connection pool worker to the backend server is in the error state, Apache will not forward any requests to that server until the timeout expires. This enables to shut down the backend server for maintenance, and bring it back online later. A value of 0 means always retry workers in an error state with no timeout.
mod_proxy - Apache HTTP Server Version 2.2

Connection pool がどうのこうの,と書いているのでバランサー向けの話かと思ったのですが,単純なリバースプロキシでも,やはりこのパラメータが効いてくるようです。デフォルトだと60秒に設定されているのですが,たしかに体感的にそのくらいでした。

なので,

ProxyPass        /app http://backend/app retry=5
ProxyPassReverse /app http://backend/app

のようにしたら,無事,再復帰が早くなるようになりました((Cache-Control ヘッダ等は必要ありませんでした))。

retry=0 にしてもよいのですが,メンテナンス中にアクセスが集中した場合,都度都度バックエンドに接続を張ろうとするのもなんだかな,と思って5秒にしてあります。これくらいでも,デバッグ中にブラウザで再確認するのに間に合ってるので特に(心理的)問題は発生していません。

まー環境によりけりな話/設定値ではあります。