photo credit: quinn.anya
WEBサーバのメンテナンス中に、サイトへの訪問者をメンテ中ゴメンね画面に飛ばすソーリーサーバーを作ったのでメモ。
実用編と銘打ちつつ、基礎編とかないのであしからず。
mod_proxy_balancerでの基本的な設定
mod_proxy_balancerにはapache httpdのマニュアルに書いてあったりなかったりするオプションで、statusというのがあります。
で、"status=+H" がついているサイトは、他が全部ダメだったらバランスするという動作をします。
DNS上ではmod_proxy_balancerが動作しているサーバをサービス用に指定して、ロードバランスするサーバからリバースプロキシで実際のWEBサーバにリクエストする格好ですね。
このような設定がこうなります、サービスサーバは複数並べてもOK。
ProxyRequests Off
<VirtualHost _default_:80>
ProxyPass / balancer://cluster/
ProxyPassReverse / balancer://cluster/
<Proxy balancer://cluster>
BalancerMember http://{普通のサービス用サーバ1} retry=5
BalancerMember http://{メンテ中画面のサーバ} status=+H
</Proxy>
</VirtualHost>
これでサービスサーバへのHTTPリクエストが可能ならサービスサーバへ、ダメならメンテ中画面のサーバにリクエストしてくれます。
これで一件落着?ていうとそこまで単純でもない。
実際飛ばすとどうなるか
前述の設定でそのまま動かすとそれはそれで別の問題が色々浮上します。
パスは残るしクエリも残るし、結局は工事中画面側のサーバでRewriteなどの処理が必要なんですよね。
他にも色々、
- リバース先がSSL
- WEBアプリが内部リンクを絶対パスで書いちゃう場合困る
などと面倒な事に対応する必要があります。
2番目のは例えば DeskNet's 、あれはリバースプロキシ泣かせです。
メニューのリンクをホストヘッダ(またはIP)から生成しよるので、初回リクエストは良くてもその後がバランスされなかったり。
懸念をつぶしていく
しかし賢いもので、それらの懸念事項にはちゃんと対応するオプションがあります。
- SSLに対応する
- これは "SSLProxyEngine On" とすればOK、SSL対応しまっせというオプション
- リンクをホストヘッダ(またはIP)から生成するアプリに対応
- "ProxyPreserveHost On" を使う。
バックエンドのサーバにHTTP1.1のホストヘッダを渡すという設定です。あんまり要らないんですが、対NeoJapan製アプリでは必須。 - URIのパス要らない、クエリ要らない
- これはひねった実装に。
結局ローカルにプロキシして、Rewriteで削ってメンテ中画面にさらに飛ばすという2段構えになりました。
詳細は次項で。
バックではパスとクエリを掃除しつつ、ブラウザのアドレス欄は書き換えない
好みが分かれる所ですが、メンテ中ページに飛ばす際にブラウザのアドレス欄を置き換えるかどうかで設定を使い分けます。
アドレス欄を置き換えると、ロードバランスしているサーバへの負荷は減るけど、サービス復帰後にF5での元のページ再読み込みができません。置き換えなければその逆。
まあ置き換えてしまったほうが楽なんですが、今回は置き換えずに工事中画面をプロキシ経由で取ってくる形にしました。
そのサンプルコンフィグがこちら。
ProxyRequests Off
<VirtualHost _default_:443>
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile {証明書へのパス}
SSLCertificateKeyFile {秘密鍵へのパス}
SSLProxyEngine On
ProxyPreserveHost On
ProxyPass / balancer://cluster/
ProxyPassReverse / balancer://cluster/
<Proxy balancer://cluster>
BalancerMember https://{普通のサービス用サーバ1} retry=5
BalancerMember http://localhost:8080 status=+H
</Proxy>
</VirtualHost>
Listen 8080
<VirtualHost _default_:8080>
DocumentRoot /var/www/html/
ServerName {任意のサーバ名}
RewriteEngine On
RewriteRule ^.*$ http://{メンテ中画面のサーバ}/maintenance.html? [P,L]
</VirtualHost>
※手元のメモには ProxyPassReverse がなかったんだが、無いと困るよなあ?
と、こんな感じにして使いましたよ。
アドレス欄云々は RewriteRule のとこだね、プロキシのPフラグにすればアドレス欄書き換え無し、Rにすればリダイレクトで書き換えされます。
受け取ったリクエストは一旦ローカルの8080に裏で飛ばし、実際は遥かなサーバからメンテナンスページだけ引っ張ってきて返してあげるという仕様になります。
アドレス欄の見た目は変わらないので、再開さえしていればユーザがF5すれば元のサービス画面に戻ります。
うまいことやればメンテ中画面もローカルに持てるので、実際そうしたほうがいいかも。
1 件のコメント:
[...] This post was mentioned on Twitter by apache_info_bot, sawanoboly. sawanoboly said: 『 mod_proxy_balancerでWEBサーバ停止時に工事中画面を見せる、実用編(apache httpd) - http://bit.ly/dAiuJj 』- SawanoBlog 2G [...]
コメントを投稿