Spring Cloud Gatewayには、APIゲートウェイとして有用なフィルター群が標準装備されています。本稿では、特に重要な熔断(サーキットブレーカー)、限速(レートリミット)、リトライの3つの機能について解説します。
リクエストパス変換フィルター
StripPrefixフィルターは、リクエストパスを指定したセグメント数分だけ削除する機能です。この機能を活用することで、特定のビジネスロジックに基づくルーティングが実現できます。
routes:
- id: path_strip_route
uri: https://target-service.example.com
predicates:
- Path=/api/v1/**
filters:
- StripPrefix=2
上記の例では、/api/v1/**にマッチしたリクエストから/api/v1の2セグメント分を除去し、https://target-service.example.com/**に転送します。例えば、http://localhost:8081/api/v1/users/123へのアクセスは、https://target-service.example.com/users/123として転送されます。
PrefixPathフィルターは、StripPrefixとは逆に、URLパスの先頭に指定したプレフィックスを追加する機能です。
routes:
- id: prefix_add_route
uri: https://backend-service.example.com
predicates:
- Method=GET
filters:
- PrefixPath=/gateway
この設定では、http://localhost:8081/p/11831586.htmlへのGETリクエストが、https://backend-service.example.com/gateway/p/11831586.htmlに変換されます。
レートリミット(限速)フィルター
高并发リクエストを処理するシステムでは、速率制限(レートリミット)が不可欠な場合があります。Spring Cloud GatewayはRedisベースの分散限速解决方案を提供しており、流量制御とシステム保护を実現できます。
まず、Redisリアクティブ対応の依存関係を追加します:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>application.ymlにはRedis接続情報とレートリミット設定を記述します:
server:
port: 8082
eureka:
client:
service-url:
defaultZone: http://eureka-server:8088/eureka/
spring:
application:
name: gateway-service
redis:
host: redis-server
port: 6379
password: ''
cloud:
gateway:
routes:
- id: rate_limited_route
uri: https://api-backend.example.com
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 50
redis-rate-limiter.burstCapacity: 100
key-resolver: "#{@clientKeyResolver}"
predicates:
- Method=GET,POST
logging:
level:
org.springframework.cloud.gateway: debug
設定パラメータの意味は以下の通りです:
- redis-rate-limiter.replenishRate:1秒あたりの許可リクエスト数(トークン補充速率)
- redis-rate-limiter.burstCapacity:令牌桶的最大容量(最大バースト容量)
- key-resolver:SpEL式でbean名を指定し、キー生成ロジックを参照
次に、キー解決ロジックを定義するConfigurationクラスを作成します。クライアントIPアドレスベースの限速と、リクエストパラメータベースの限速の両方を実装できます:
package com.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimitConfig {
/**
* クライアントIPアドレスベースのキー解決ロジック
*/
@Bean
public KeyResolver remoteAddressKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getHostAddress()
);
}
/**
* リクエストパラメータベースのキー解決ロジック
*/
@Bean
public KeyResolver parameterKeyResolver() {
return exchange -> Mono.justOrEmpty(
exchange.getRequest().getQueryParams().getFirst("client_id")
);
}
}
サーキットブレーカー(熔断)フィルター
バックエンド服务的可用性が低下した場合に備え、Spring Cloud GatewayはNetflix Hystrixとの統合による熔断功能を提供します。异常发生时、自动的にフォールバック路径にリクエストを転送します。
Hystrix依存関係を追加します:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>ルーティング設定では、Hystrixフィルターを指定し、フォールバックURIを定義します:
routes:
- id: circuit_breaker_route
uri: lb://microservice-provider
predicates:
- Path=/service/**
filters:
- name: Hystrix
args:
name: fallbackCommand
fallbackUri: forward:/fallback-handler
フォールバックURIには、内部サービスまたはフィルター鏈路内でハンドリング可能な 경로 を指定します。Hystrixが熔断状態を触发すると、请求は指定されたフォールバック路径に转发されます。
リトライフィルター
RetryGatewayFilterは、一時的な障害に対するリクエスト自动再試行機能を提供します。ネットワーク不安定や一時的な服务异常に対して効果的な対策となります。
routes:
- id: retry_route
uri: lb://downstream-service
predicates:
- Path=/retry/**
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
methods: GET,POST
series: SERVER_ERROR
各パラメータの詳細な説明は以下の通りです:
- retries:最大再試行回数(デフォルトは3回)
- statuses:再試行をトリガーするHTTPステータスコード(org.springframework.http.HttpStatus参照)
- methods:再試行を適用するHTTPメソッド(デフォルトはGETのみ、org.springframework.http.HttpMethod参照)
- series:再試行対象のステータスコードシリーズ(デフォルトはSERVER_ERROR = 5XX)
ステータスシリーズにはSERVER_ERROR以外にも CLIENT_ERROR (4XX)、REDIRECTION (3XX) 等等灯があり、柔軟な設定が可能です。