RequestRateLimiter GatewayFilter ファクトリ

RequestRateLimiter GatewayFilter ファクトリは、RateLimiter 実装を使用して、現在のリクエストの続行が許可されているかどうかを判別します。そうでない場合は、HTTP 429 - Too Many Requests のステータス(デフォルト)が返されます。

このフィルターは、オプションの keyResolver パラメーターと、レートリミッターに固有のパラメーターを受け取ります ( このセクションで後述します )。

keyResolver は、KeyResolver インターフェースを実装する Bean です。構成では、SpEL を使用して Bean を名前で参照します。#{@myKeyResolver} は、myKeyResolver という名前の Bean を参照する SpEL 式です。次のリストは、KeyResolver インターフェースを示しています。

KeyResolver.java
public interface KeyResolver {
	Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver インターフェースにより、プラグ可能な戦略がリクエストを制限するための鍵を導き出すことができます。将来のマイルストーンリリースでは、いくつかの KeyResolver 実装があります。

KeyResolver のデフォルトの実装は PrincipalNameKeyResolver です。これは、ServerWebExchange から Principal を取得し、Principal.getName() を呼び出します。

デフォルトでは、KeyResolver がキーを見つけられない場合、リクエストは拒否されます。この動作は、spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true または false)および spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code プロパティを設定することで調整できます。

RequestRateLimiter は、「ショートカット」表記では構成できません。以下の例は無効です:

# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

有効な yaml 参照は次のとおりです。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: limit
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            key-resolver: "#{@userkeyresolver}"

Redis RateLimiter

Redis の実装は、ストライプ (英語) で行われた作業に基づいています。spring-boot-starter-data-redis-reactive Spring Boot スターターを使用する必要があります。

使用されるアルゴリズムはトークンバケットアルゴリズム [Wikipedia] (英語) です。

redis-rate-limiter.replenishRate プロパティは、許可する 1 秒あたりのリクエスト数を定義します (リクエストのドロップなし)。これは、トークンバケットが満たされる速度です。

redis-rate-limiter.burstCapacity プロパティは、ユーザーが 1 秒間に許可されるリクエストの最大数です (ドロップされたリクエストはありません)。これは、トークンバケットが保持できるトークンの数です。この値をゼロに設定すると、すべてのリクエストがブロックされます。

redis-rate-limiter.requestedTokens プロパティは、リクエストにかかるトークンの数です。これは、リクエストごとにバケットから取得されたトークンの数であり、デフォルトは 1 です。

replenishRate と burstCapacity に同じ値を設定すると、安定したレートが実現されます。burstCapacity を replenishRate より高く設定することにより、一時的なバーストを許可できます。この場合、2 つのバーストが連続するとリクエストが破棄される (HTTP 429 - Too Many Requests) ため、レートリミッタはバースト間にある程度の時間を許可する必要があります ( replenishRate に従って)。次のリストでは、redis-rate-limiter を構成しています。

1 request/s 未満のレート制限は、replenishRate を必要なリクエスト数に設定し、requestedTokens を秒単位のタイムスパンに設定し、burstCapacity を replenishRate と requestedTokens の積に設定することによって達成されます。例: replenishRate=1requestedTokens=60burstCapacity=60 を設定すると、制限が 1 request/min になります。.application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20
            redis-rate-limiter.requestedTokens: 1

次の例では、Java で KeyResolver を構成します。

Config.java
@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

これにより、ユーザーあたり 10 のリクエストレート制限が定義されます。20 のバーストが許可されますが、次の 1 秒間は 10 のリクエストしか使用できません。KeyResolver は、user リクエストパラメーターを取得する単純なものです。注: これは本番環境では推奨されません。

レートリミッタを、RateLimiter インターフェースを実装する Bean として定義することもできます。構成では、SpEL を使用して Bean を名前で参照できます。#{@myRateLimiter} は、myRateLimiter という名前の Bean を参照する SpEL 式です。次のリストは、前のリストで定義された KeyResolver を使用するレートリミッタを定義しています。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@myRateLimiter}"
            key-resolver: "#{@userKeyResolver}"