はじめに:
今回は最近お客様からよく相談されるWebサイト運営時の悩みと解決策について考えてみたいと思います。今日のWebサイトでは、いつ突発的なトラフィックが発生するか予想がつきにくいのではないでしょうか。

キャンペーンやイベント告知など、サイト管理者がある程度予測が可能なトラフィック増であればそれなりの事前対応ができますが、予期しないトラフィック増が発生してしまうと、対策も遅れ、サーバのリソースを使いきり、結果的にレスポンスの遅延やサーバダウンにつながる恐れさえでてきます。

このような特性をもつトラフィックは、サーバに到達する前に適切なトラフィックコントロールをしてあげるのがよいのではないでしょうか?こんな時、サーバの前段にあるBIG-IPが大きな役割を果たせます。

たとえばコネクションリミット。この機能はBIG-IP側で滞留TCPコネクションをカウントし、あらかじめ設定しておいて閾値を上回った場合には、新規のコネクションについてはTCPリセットやSorryサーバへリダイレクトさせるというソリューションです。こちらは、BIG-IPをご利用の方なら一度は聞いたことがあるソリューションではないでしょうか。

「コネクションリミットもいいけど、例えば、新規リクエストをカウントして、1分あたりの新規接続数に制限をかけたい」というご要望を最近よくお客様からいただくことがあります。
こんな時、今回ご紹介するiRulesが一つの解決案になるのではないかと考えています。

iRulesを普段ご利用のみなさんは、iRulesはイベントドリブン型だとご存じだと思います。HTTPリクエストがクライアントからBIG-IPに届いたら特定の処理を行うというような場合は、以下のような構文になります。

when HTTP_REQUEST {
  { 処理 1 }
  { 処理 2 }
}

つまり、ほとんどの場合iRulesを実行するタイミングはトラフィックがBIG-IPを通過するタイミングになります。したがって今までは前述のようなお客様の要望に残念ながら対応できませんでした。
(イベント発生時に時刻を保存し、次回のイベント時に前回の時刻と比較して経過時間を算出することで、工夫しだいで似たような機能をiRulesで実装することはできたりもしますが)

そんなご要望が多くあった影響かはわかりませんが、ついにタイマー機能を実現するコマンドがiRulesで利用できるようになりました。こちらで周期的な処理を実装することができます。コマンド名は"after"です。"after"は、先日発表したBIG-IPの最新バージョンである v10 からご利用になれます。

以下でも詳細をご確認いただけます。
http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=348

今回はこの便利な"after"を使った例で、1分あたりの新規ユーザリクエスト数の制限を設けるiRulesをご紹介します。こちらを応用してご活用いただければと思います。

タイトル:
タイマーを使い1分あたりの新規ユーザリクエスト数に制限を設けるiRule

メリット:

このiRulesを利用すると、新規のリクエストが単位時間あたりの閾値を超えた場合にサーバへのトラフィック転送を防ぎ、サーバリソースを保護することができます。また、タイマーを利用すると、以下のような処理を実装することもできます。

  • アプリケーション応答時間の遅延を検出すること
  • トラフィックに含まれる情報のレート(単位時間あたりの処理量)を計測すること
  • 定期的な処理を実行すること

機能解説:
タイマーを実装するコマンドは"after"です。
周期的な処理を実行させたい場合には、"-periodic"をつけます。

after <ms> [-periodic] <script>

設定概要:

この例ではシンプルに、HTTPリクエスト中のCookieの有無により、既存ユーザリクエストか新規ユーザリクエストかどうかを判別しています。Cookieの文字列を変更したい場合は以下の"UserID"の部分を変更することにより対応できます。

[HTTP::cookie exists "UserID"]

また、1分あたりの新規ユーザ数は以下の部分の"100"の部分を変更することにより対応できます。この例では、新規リクエスト分間100リクエストまでという設定になっています。

$::new_user_count > 100

制限値を超えたリクエストに対しては、BIG-IPがサーバにリクエストを転送せず、HTTP 503のレスポンスをクライアントに返す設定になっています。以下を変更することにより、返したいHTTP レスポンスコードを設定できます。

HTTP::respond 503 Retry-After 3

また、この部分を以下にすることでBIG-IP上でパケットを破棄することもできます。

discard

【iRule定義】


when RULE_INIT {
set new_user_count 0
after 60000 -periodic {
set new_user_count 0
}
}
when HTTP_REQUEST {
if { not ([HTTP::cookie exists "UserID"]) } {
incr ::new_user_count
if { $::new_user_count > 100 } {
HTTP::respond 503 Retry-After 3 }
}
}

 

 ※F5ネットワークスジャパンでは、サンプルコードについて検証を実施していますが、お客様の使用環境における動作を保証するものではありません。実際の使用にあたっては、必ず事前にテストを実施することを推奨します。