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 ......
mod_proxy - Apache HTTP Server Version 2.2
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.
Connection pool がどうのこうの,と書いているのでバランサー向けの話かと思ったのですが,単純なリバースプロキシでも,やはりこのパラメータが効いてくるようです。デフォルトだと60秒に設定されているのですが,たしかに体感的にそのくらいでした。
なので,
ProxyPass /app http://backend/app retry=5 ProxyPassReverse /app http://backend/app
のようにしたら,無事,再復帰が早くなるようになりました((Cache-Control
ヘッダ等は必要ありませんでした))。
retry=0
にしてもよいのですが,メンテナンス中にアクセスが集中した場合,都度都度バックエンドに接続を張ろうとするのもなんだかな,と思って5秒にしてあります。これくらいでも,デバッグ中にブラウザで再確認するのに間に合ってるので特に(心理的)問題は発生していません。
まー環境によりけりな話/設定値ではあります。