HAProxyにぶら下がるサーバやサービスを高負荷時に守りたい場合、be_sess_rate
とACLを連携させることによって、閾値を超えた新規セッションを別のバックエンドに流す、ということが可能です。
かんたんに構成を書くと以下のようになります。バックエンドにはNginxを使用しています。
コンフィグは以下の通りです。秒間の新規セッションの上限を1000としています。
# フロントエンドの設定
frontend frontend_001
bind *:80
# バックエンドのセッションが1000を超えた場合、be_is_busy が真となる
acl be_is_busy be_sess_rate(backend_nginx) gt 1000
# be_is_busy が真の場合のみ、busy用バックエンドを使用する
use_backend backend_busy if be_is_busy
# 通常は、デフォルト用バックエンドを使用する
default_backend backend_nginx
# デフォルト用のバックエンド
backend backend_nginx
balance roundrobin
server nginx-001 192.168.100.101:80
server nginx-002 192.168.100.102:80
server nginx-003 192.168.100.103:80
# Busy用バックエンド
backend backend_busy
balance roundrobin
server nginx-004 192.168.100.104:80
server nginx-005 192.168.100.105:80
なお、be_sess_rate
について、公式ドキュメントには以下のように載っています
be_sess_rate([]) : integer
Returns an integer value corresponding to the sessions creation rate on the backend, in number of new sessions per second. This is used with ACLs to switch to an alternate backend when an expensive or fragile one reaches too high a session rate, or to limit abuse of service (eg. prevent sucking of an online dictionary). It can also be useful to add this element to logs using a log-format directive.
この中の、"sessions creation rate" がピンとこなかったのですが、実験の結果、秒間のセッション数は、秒間のリクエスト数とほぼ同じということがわかりました。
なお、バックエンドのBusy用サーバを用意しなくても、HAProxy自体が静的コンテンツを返答することも可能です。その際は、バックエンドを以下のようにすると良いでしょう。(注意:503以外は使用できません)
# Busyコンテンツを直接返答
backend backend_busy
mode http
errorfile 503 /usr/share/haproxy/busy.http
これで、1秒当たり1000リクエストを超えたら、その分はBusyを返す、ということができました。