VCL カウンターとリミッター

この情報は、限定公開されているリリースの一部に関するものです。詳細については、製品と機能のライフサイクルの説明をご覧ください。

Fastly では、要素とそのカウントを追跡するコンテナとして機能するカウンターとリミッターの2つのデータタイプを VCL で利用できます。これらは、オリジンサーバーを不正利用から守るレート制限の実装などに使用できます。

カウンターとリミッターは通常エッジで動作し、Fastly POP 内のカウントを同期させます。また、シールド POP でもカウンターとリミッターを使用できます。シールドでカウントを実行すると、トラフィック量によって精度が低下する可能性があります。現在、1サービスにつき使用できるカウンターの数は5つに制限されています。この上限の増加については、サポートチームまでお問い合わせください

カウンター

カウンターデータタイプでは、さまざまなパラメーターを有する VCL カウンターを定義することができます。定義されたら、カウンターは、counter.inc()counter.get() の関数を使用し、それぞれ現在の値をインクリメントして取得することができます。例:

counter counter_login {
.type = "estimated";
.time_window = 60s;
}

counter のデータタイプには以下のフィールドがあります。

フィールド説明
.typeカウンターのタイプ。 有効なタイプは estimated のみです。
.time_windowカウンターがインクリメントを蓄積する期間。 推定カウンターにのみ適用されます。 最小は60秒 (1分)、最大3600秒 (1時間) です。 設定された期間が過ぎると、蓄積されたカウントの一部が次のウインドウに移動します。

counter.get()

カウンターの状態を INTEGER として返します。 返される整数は、指定されたキーのカウンターの現在の値を反映します。

例:

counter my_counter { .time_window = 60s; .type = "estimated"; }
sub vcl_deliver {
set resp.http.my_counter_val = counter.get(my_counter, "deliver");
}

counter.inc()

カウンターのインクリメント状態を INTEGER として返します。 返される整数は、指定されたキーのカウンターの現在の値を反映します。

例:

counter my_counter { .time_window = 60s; .type = "estimated"; }
sub vcl_deliver {
set resp.http.my_incr_counter_val = counter.inc(my_counter, "deliver");
}

リミッター

リミッターデータタイプはカウンターと同様に動作し、カウントを追跡するコンテナを定義することができます。 定義されたら、リミッターは limiter.inc()limiter.get() の関数を使用し、それぞれ現在の値をインクリメントして取得することができます。 例:

limiter limiter_login {
.max = 50;
.time_window = 60s;
}

limiter のデータタイプには以下のフィールドがあります。

フィールド説明
.maxこのレートリミッターに設定できる最大値です。
.time_windowカウンターがインクリメントを蓄積する期間。 最小は60秒 (1分)、最大3600秒 (1時間) です。

limiter.inc()

レートリミッターの状態について、カウントが指定されたしきい値を超えた場合は BOOL、超えない場合は falsetrue 値で返します。

例:

my_limiter が定義されたしきい値を超える場合、true が返されます。 my_limiter が定義されたしきい値を超える場合、false が返されます。

limiter my_limiter { .time_window = 60s; .max = 50; }
sub vcl_deliver {
set resp.http.limiter_state = if(limiter.get(my_limiter, client.ip), "under", "over");
}

limiter.get()

レートリミッターのインクリメント状態を返します。 カウントが指定されたしきい値を超える場合、true の BOOL 値を返し、そうでない場合は false を返します。

例:

my_limiter が定義されたしきい値を超える場合、true が返されます。 my_limiter が定義されたしきい値を超える場合、false が返されます。

limiter my_limiter { .time_window = 60s; .max = 50; }
sub vcl_deliver {
set resp.http.limiter_state = if(limiter.inc(my_limiter, client.ip), "under", "over");
}

使用例: レート制限

カウンターとリミッターを使用することで、レートリミッターを実装し、オリジンサーバーを不正利用から保護することができます。特に、カウンターウィンドウの「キャリーオーバー」動作によって、連続時間ウィンドウに近づけることができます。これにより、各ウィンドウの有効期限が切れた際に突然、値が低下しないようにレート制限を決定する作業などにおいて、.time_window() の関数が特に役立ちます。

この動作を活用し、.time_window() 内の総カウント数をウィンドウの長さで割ることで、1秒あたりのリクエスト数で表示されるメッセージレートを取得できます。ウィンドウ内のリクエスト数の合計を確認することで、さまざまなタイプの過剰なトラフィック攻撃から保護することができます。