はじめに
- mod_proxy_balancer の振り分け挙動について調べた
- mod_proxy_balancer の failonstatus の挙動についても調べた
参考
検証環境
環境
以下のような構成で確認を行った。
| 役割 | IP | 備考 |
|---|---|---|
| proxy_balancer | 172.17.0.96 | Server version: Apache/2.2.22 (Debian) |
| worker | 172.17.0.97 | Server version: Apache/2.2.22 (Debian) |
| worker | 172.17.0.98 | Server version: Apache/2.2.22 (Debian) |
全ての環境は docker のコンテナを利用してセットアップについてはこちらの cookbook を利用した。
proxy_balancer の設定
以下のような設定で proxy_balancer の設定を行った。
モジュールを有効化
a2enmod を使ってモジュールを有効にする。
sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_connect sudo a2enmod proxy_balancer
これは便利。
proxy_balancer.conf
/etc/apache2/mods-enabled/proxy_balancer.conf を以下のように設定。
<IfModule mod_status.c>
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Deny from all
#Allow from 127.0.0.1 ::1
Allow from all # 今回は検証の為に from all だけど実運用の際は適宜 IP 等を設定する
Satisfy all
</Location>
</IfModule>
ProxyPass /test balancer://test
<Proxy balancer://test>
BalancerMember http://172.17.0.97 loadfactor=10
BalancerMember http://172.17.0.98 loadfactor=10
</Proxy>
balancer-manager も有効にしておく。
検証結果
検証手順
以下のような手順で意図的に任意のステータスコードを proxy_balancer に返却するように worker を調整した。
| 状態 | ステータスコード | 備考 |
|---|---|---|
apache を停止 |
N/A | invoke.d apache2 stop にて停止 |
index.html が存在しない |
404 | a2dismod autoindex で autoindex を無効化 |
| ディレクトリの参照権限を削除 | 403 | /var/www を chmod 700 でアクセスを拒否 |
| cgi スクリプトにバグを発生 | 500 or 503 | mime.conf を修正し .cgi を有効化 |
結果
検証結果ついては、上記の状態において Load Balancer Manager の Status を確認した。

以下、結果を整理したもの。
| 状態 | ステータスコード | Status | 振り分け |
|---|---|---|---|
apache を停止 |
N/A | Err | しない |
index.html が存在しない |
404 | OK | してしまう |
| ディレクトリの参照権限を削除 | 403 | OK | してしまう |
| cgi スクリプトにバグを発生 | 500 | OK | してしまう |
上記から mod_proxy_balancer のデフォルト設定では 完全に worker のプロセスが停止しないと mod_proxy_balancer はトラフィックを割り振り続ける。
failonstatus を試してみる
素の状態の mod_proxy_balancer だとバックエンドの worker の死活をプロセスレベルでは判断出来るがステータスコードレベルでは判断出来ていないようだ。それを回避するオプションとしてfailonstatus が使えるみたいので試してみる。
設定
/etc/apache2/mods-enabled/proxy_balancer.conf を以下のように修正する。
<Proxy balancer://test> BalancerMember http://172.17.0.97 loadfactor=10 BalancerMember http://172.17.0.98 loadfactor=10 ProxySet failonstatus=500 </Proxy>
ProxySet failonstatus=500 を追加して、worker がステータスコード 500 を返す場合にはエラーと判断してトラフィックを割り振らないようにする。また、複数のステータスコードを指定する場合にはカンマ区切りでステータスコードを書いていく。以下のような感じ。
<Proxy balancer://test> BalancerMember http://172.17.0.97 loadfactor=10 BalancerMember http://172.17.0.98 loadfactor=10 ProxySet failonstatus=500,403,404 </Proxy>
確認
worker の一台(例は http://172.17.0.98 )でステータスコード 500 を返すようにして Load Balancer Manager で確認すると...

おお、ちゃんと Err を返すようになっている。
最後に
- 従来はフワッとしか
mod_proxy_balanacerの挙動について理解しておらず、wokerが停止してしまうような障害が発生したら慌ててworkerの切り離しをしていたことが恥ずかしいw failonstatusのオプションを効率よく利用して可用性を高めていきたいLoad Balancer Managerはブラウザベースでworkerの切り離し等が動的に行えるので非常に便利(迂闊に使うと大変なことになるけども...)