BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース .NETの新パッケージ System.Threading.RateLimiting

.NETの新パッケージ System.Threading.RateLimiting

ブックマーク

原文(投稿日:2021/08/06)へのリンク

レート制限(rate limiting)はWebサーバの問題として広く知られているが、同じような機能が必要になる状況は他にもたくさんある。例えば、クライアントアプリケーション自体にレート制限を組み込んでおけば、Webサーバの制限が実行されなくなるというメリットがある。ファイルサーバやデータベースサーバなどのリソースでも、独占を防ぐ上でレート制限が必要になる場合もある。

理論的には、セマフォを使用すれば独自のレート制限機構を構築できるが、この方法はエラーを発生させやすい可能性がある。そのため.NETでは、System.Threading.RateLimitingという、新たなパッケージが提供されることになった。このパッケージは、レート制限の共通フレームワークを定義した上で、いくつかのレート制限オプションをアウト・オブ・ボックスで提供するものだ。

すべてのレート制限クラスは、RateLimiterというシンプルな名称の抽象基本クラスを実装しなければならない。このクラスは、リースを同期的および非同期的に取得する方法に加えて、利用可能なリース数を提供する。リース(lease)はパーミット(permit)とも呼ばれ、処理の実行に対するレート制限からの許可である。この許可はRateLimitLeaseクラスとして表現され、現在のタスクが完了した時点でプールにリースバックしなければならない。

組み込み型のレート制限は現在提案中である。最も単純なのはConcurrencyLimiterで、セマフォと同様に、一定数の並行ワーカ(concurrent worker)のみを実行可能にする。

それに続く2つのオプションは、FixedWindowRateLimiterSlidingWindowRateLimiterで、それぞれの名前が示すように、特定の時間枠におけるリクエスト数を制限する。前者はカウントのリセットに単純な時間枠を使用する。後者はより高度なオプションで、時間窓をN個のセグメントにスライスし、各セグメントにリクエストカウンタを持たせている。

最後のオプションであるTokenBucketERateLimiterトークンバケット(token bucket)アルゴリズムにヒントを得たものだ。一般的にワーカが取得するのは単一のリースだが、複数のリースを一度に必要とするシナリオも存在する。例えば、それぞれのリースがCPU Coreとメモリブロックの許可を表現しているような場合だ。このようなケースでは、TokenBucketRateLimiterを使うとより便利である。時間の限定されたバケット単位で、各ワーカが要求するリース数と使用可能なリース数に基づいたリクエストの整理が可能になる。

レート制限によってリース要求を受け入れられない場合の動作はさまざまだ。同期処理では、RateLimitLeaseが失敗を示すフラグを返す。

非同期処理の場合、リクエストは順番がくるまでキューされるが、キューが設定された制限値より大きくなると、ワーカがキューからリジェクトされる。この場合、リジェクト対象を最古のリクエストにするか、あるいは最新のリクエストにするかを、プログラマが設定できる。

このライブラリが明示的にサポート対象外としているユースケースのひとつが、集約型(aggregated)リミッタである。レート制限の提案によると、

集約型リミッタが必要なシナリオをサポートするためには、ここで提案されたものとは異なる、別の抽象化が必要になります。

IPによるレート制限のようにカーディナリティ(cardinality)の高いリミッタでは、バケット毎のレート制限(IPアドレス毎にひとつのレートリミッタ、というように)は望ましくありません。そのためには、IDを渡すことのできるAPIが必要になりますが、これにはデフォルトキーを渡すという面倒な操作が伴います。Nリクエスト/秒という制限のような、キーを必要としないシンプルなリミッタとは対照的です。従って、ここで提案するような、単純なAPIの方が望ましいのです。

さらに、集約型リミッタのユースケースは、今のところdotnet/ランタイムには見当たりません。それもあって、今回の提案には含めていないのです。最終的に、このような集約型リミッタがBCLでも必要であると判断されたならば、ここで提案したAPIとは別に追加すればよいでしょう。

この役割は、AspNetCoreRateLimitのような、特にASP.NET Core用に開発されたパッケージが果たすことになる。

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

コミュニティコメント

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

BT