0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kong Gatewayを使って帯域幅のスロットリングを実現する

Last updated at Posted at 2025-10-16

Kong Gatewayを使うと流量制限が出来るのは知ってる人は知ってる話だが、これまではリクエスト数が一定数を超えると429 Too Many Requestsを返すという機能のみ提供されており、帯域幅に基づくスロットリングはサポートされていなかった。
10月にリリースされたKong Gatewayのv3.12に付随するRate Limiting Advanced Pluginではスロットリングがサポートされ、429ステータスコードで即座に拒否されるのではなく、遅延して再試行することが出来るようになった。
これを実際に試してみた。

Rate Limiting Advanced Pluginの設定

スロットリングに関する以下の4つのパラメータが追加されている。

パラメータ 意味
config.throttling.enabled スロットリングを有効にするかどうか。デフォルトはfalse
config.throttling.interval スロットリングされた個々のリクエストの再試行間隔。デフォルトは5
config.throttling.queue_limit スロットリングキューの最大長。デフォルトは5
config.throttling.retry_times スロットリングされたリクエストの再試行回数。デフォルトは3

発動条件についてはこれまで通りwindow_sizelimitで設定する。

イメージとしてはこんな感じ。
20251016153541.png

limitを超えた分は一旦キューに入れられ、intervalで指定された秒数ごとにキューから取り出されて処理される。
スロットリングを設定しているにも関わらず429を返すのは以下のケースで、1つはキューから溢れる場合で、queue_limitを超えてリクエストを受け取ると429が返される。
20251016154105.png

キューの上限は1000000なので、キュー溢れを許さないような場合は適切に設定したい。
もう1つはリトライ回数を超えた場合。
20251016153652.png

window_sizeに対してintervalが極端に小さい場合は単一リクエストでも429が返されることがあるので注意が必要そう。

検証

今回は以下のようなdeck用のYAMLを用意して試してみた。

_format_version: "3.0"
services:
- enabled: true
  host: httpbin.konghq.com
  name: httpbin-service
  path: /
  port: 443
  protocol: https
  routes:
  - name: httpbin-route
    paths:
    - /httpbin
    plugins:
    - config:
        limit:
        - 3
        namespace: namespace
        strategy: local
        throttling:
          enabled: true
          interval: 5
          queue_limit: 5
          retry_times: 3
        window_size:
        - 10
        window_type: sliding
      enabled: true
      name: rate-limiting-advanced

ServiceとしてKong社がホスティングしているhttpbinを指定し、Routeのパスには/httpbinを指定している。
Rate Limiting Advanced PluginをRouteにアタッチし、10秒間に3リクエストを超えた場合にスロットリングが発動するように設定している。

設定後検証を行う。以下のようにして短期間に10回連続でリクエストを送り、ステータスコードとKong本体のレイテンシを確認する

for((i=0;i<10;i++)) ; do curl -s localhost:8000/httpbin -I |grep "HTTP\|X-Kong-Proxy-Latency" ; done

上手く動作すれば、4回目以降のアクセスがエラーは返らないものの遅くなるはずだ。
実際に実行した結果は以下のような感じになる。

HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 2
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 2
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 4
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5007
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5007
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5006
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 3
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5001
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5006
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 5006

4回目以降、X-Kong-Proxy-Latencyが5秒以上になっているのが分かる。
これにより、429ステータスコードを返すことなく、リクエストが遅延されていることが分かる。
また7回目のレイテンシは3msになっているが、これは流量制限の解除秒数が経過したためだと考えられる。
次に429ステータスコードが返されるケースを試してみる。
429を返すのはキューから溢れた時かリトライ回数を超えたときなので、まずはキューから溢れるケースを試してみる。
キューの上限を1に変更し、2つのターミナルから同時に先程のfor文を実行する。
ターミナル1の実行結果は以下。

HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 3
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
:(省略)

ターミナル2の実行結果は以下。

HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 1
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 1
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15011
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
;(省略)

4回目以降の実施で、キューに入ったものだけ遅延して送られ、それ以外のものは429が返されているのが分かる。
なお、キューから削除されるのがレスポンスを受け取って、次のリクエストを送った後っぽく、ターミナルを複数用意しなくても単一のfor文でもキュー数が1であれば再現できる。
(バグのような気がするのでそのうち修正されるかも)
次にリトライ回数を超えた場合を試してみる。
単一の実行でリトライ数を超えるにはおおよそwindow_size>interval*retry_timesを満たせばよいので、ここでは余裕を持たせてwindow_sizeを30にして確認してみる(キューサイズは元の3に戻す)。

HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 1
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 2
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 0
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15011
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15009
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15009
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15007
HTTP/1.1 200 OK
X-Kong-Proxy-Latency: 15005

期待した通り、4回目で429が返されているのが分かる。
ただ、6回目以降は遅延しているものの429は返されていない。
これはある程度時間が経つことでwindow_size範囲内のリクエスト数がlimitを下回り、再びリクエストが通るようになったためと考えられる。

所感

今回の検証により、Rate Limiting Advanced Pluginでスロットリングがサポートされたことが確認できた。
リクエスト数超過時に拒否はせずにサービスの質を落として継続したいケースもあると思う。
この機能追加によりその要望にも使えるようになったのは有り難い。
一方で、帯域幅の指定とかが出来るわけではないので、パラメタチューニングはやや難度が高いかと感じた。
使いこなすにはある程度テストとかを繰り返す必要がありそう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?