基于spring-cloud-gateway实现自己的网关过滤器
spring cloud gateway custom starter
自定义非阻塞式反应网关服务,集成鉴权、限流、响应的增强处理等等
- 环境要求
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<java.source.version>17</java.source.version>
<java.target.version>17</java.target.version>
<spring-boot.version>3.1.12</spring-boot.version>
<spring-cloud.version>2022.0.5</spring-cloud.version>
<commons.pool2.version>2.12.0</commons.pool2.version>
<redisson.version>3.34.1</redisson.version>
<com.fastjson.jackson.version>2.17.2</com.fastjson.jackson.version>
<commons.lang3.version>3.16.0</commons.lang3.version>
<lombok.version>1.18.32</lombok.version>
</properties>
- GatewayFilter 路由过滤器
- TokenFilterGatewayFilterFactory,鉴权处理
- 配置示例:
spring:
cloud:
gateway:
routes:
- id: testRoute
uri: http://127.0.0.1:8080
predicates:
- Path=/test/**
filters:
- name: TokenFilter
args:
requestHeaderKey: auth
自定义网关过滤工厂实现,TokenFilterGatewayFilterFactory和RlimterGatewayFilterFactory,以自定义限流器RlimterGatewayFilterFactory为例
- 首先定义网关过滤工厂功能接口,限流的key,速率和桶的大小,我们是按照spring-cloud-gateway内部限流的实现改编而来的,通过调用lua脚本,采用redis的令牌桶算法做限流
public interface RLimter {
Mono<Response> isAllowed(String limitKey, String rate, String crust);
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
class Response {
private boolean allowed;
}
}
- 限流功能组件的注入和声明,注入我们需要的Bean,注入RedisScript,调用自定义的lua脚本,以及StringRedisTemplate,因为下面这段代码我是将整个网关作为的启动器,所以限流的实现类也一并交给spring管理了,RRedisRateLimiter
@Configuration
public class RLimterAutoConfiguration {
@Bean(name = "rredisRequestRateLimiterScript")
public RedisScript<?> redisRequestRateLimiterScript() {
DefaultRedisScript redisScript = new DefaultRedisScript();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/request_rate_limiter.lua")));
redisScript.setResultType(List.class);
return redisScript;
}
@Bean(name = "rredisRateLimiter")
public RRedisRateLimiter redisRateLimiter(@Qualifier("rredisRequestRateLimiterScript") RedisScript<List<Long>> redisRequestRateLimiterScript, StringRedisTemplate redisTemplate) {
return new RRedisRateLimiter(redisTemplate, redisRequestRateLimiterScript);
}
@Bean
public RLimterGatewayFilterFactory rLimterGatewayFilterFactory(@Qualifier("rredisRateLimiter") RRedisRateLimiter redisRateLimiter) {
return new RLimterGatewayFilterFactory(redisRateLimiter);
}
}
- 上面代码中提到的new ClassPathResource(“script/r