こういうネタは需要があるのかわかりませんが、昔やったことを残しておきます。
LoadBalancer配下のアプリサーバが異常をきたしてLBから切り離しするってのは良くあることだと思います。
けど、接続数があふれて接続できないといったLBで検知可能な異常だったらLB側で制御可能ですが、接続できるけどなんか不調っていう状況だと、LBで切り離しを制御するのって難しいですよね。
こんな時はアプリサーバ側で異常検知をする仕組みを作って、iptablesでLBからの流入を遮断しちゃいましょう。
if [ 異常発生? ]
then
NUM=`/sbin/iptables -L INPUT -n --line-number | grep dpt:80 | awk '{print $1}'`
/sbin/iptables -I INPUT ${NUM} -m state --state NEW -s {LBのIP/mask} -p tcp --dport 80 -j REJECT
fi
今回の例だとLB配下のWebアプリサーバを想定しているので、80番ポートへのアクセス許可をしているINPUTルールの番号 ${NUM} を調べて、その直前にsource IPがLBのIPアドレスだったら新規の接続はREJECTするよ、というルールを iptables の-Iオプションで挿入するのがポイントです。
REJECTにしとくとLBからのsynに対して即時にエラーパケットを返すのですが、DROPだとパケットを捨てて何も応答を返さないので、LB側はパケロスと誤認しちゃって輻輳制御と同様のsynの再接続処理に陥ってしまいます。
あとは上記のスクリプトに、異常検知やすでにREJECTルールが存在する時などの例外処理の肉付けをしていけばいい感じになるんじゃないでしょうか。
※異常によってはアプリサーバ全台切り離されるかもしれないのが悩ましいところですが・・・
異常状態から復旧する際は、REJECTのルールを削除すればいいので、REJECTルールの番号を調べて、その番号を削除するコマンドを iptables の-Dオプションで投げればOKです。
NUM=`/sbin/iptables -L INPUT -n --line-number | grep dpt:80 | grep REJECT | awk '{print $1}'`
/sbin/iptables -D INPUT ${NUM}
ではでは。