Spring Gateway 限流实现

119 阅读1分钟

添加依赖

网关限流提供了基于Redis的实现,首先引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

配置Redis

spring:
  redis:
    host: 127.0.0.1
    port: 6379

注意:此处配置需要严格按照官方要求的配置。

配置过滤器

- id: service_route
  uri: lb://demo-service
  predicates:
	- Path=/api/**
  filters:
	- SecureHeaders
	- AddResponseHeader=Cache-Control,no-cache
	- name: RequestRateLimiter #请求数限流,名字固定
	  args:
		key-resolver: "#{@userKeyResolver}"
		redis-rate-limiter.replenishRate: 1 #生成令牌速率-设为1方便测试
		redis-rate-limiter.burstCapacity: 1 #令牌桶容量-设置1方便测试
		redis-rate-limiter.requestedTokens: 1 # 每次请求获取的令牌数

限流过滤器(RequestRateLimiter)可以和其他过滤器同时配置。

指定限流Key

@Slf4j
@Component(value = "userKeyResolver")
public class UserKeyResolver implements KeyResolver {

    private static final String BJWT = "bjwt";

    private static final String USERID = "userId";

    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        log.info("进入频率拦截...");
        ServerHttpRequest req = exchange.getRequest();
        HttpHeaders httpHeaders = req.getHeaders();
        String jwt = httpHeaders.getFirst(BJWT);
        Map<String, String> map = JwtUtil.decrypt(jwt); // 解析jwt
        String userId = map.get(USERID);
        return Mono.just(userId);
    }
}

此处演示的是以用户ID为限流key来进行限流,用户ID从JWT中提取。可以基于IP、接口等实现其他维度的限流。