Spring Cloud GateWay的坑
坑1:GatewayFilter只能在代码中配置,无法在配置文件中配置
举例:自定义一个GatewayFilter, public class AuthorizationFilter implements GatewayFilter, Ordered
,这种bean类型的实现方法看起来很简洁,但是如果你想在配置文件中去配置这个过滤器,启动就会报错,无法找到对应的FilterFactory错误,这是因为配置文件只识别GatewayFilterFactory所衍生的子类,用GatewayFilter的子类只能在代码中用路由规则配置;
坑2:路由中filters和filter要谨慎使用
举例:自定义路由有filters和filter两种选择
先看正确配置方法:
@Bean
@Order
public RouteLocator customRouteLocator(RouteLocatorBuilder builder,
RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory,
IpFilter ipFilter,
AuthFilter authFilter) {
RequestRateLimiterGatewayFilterFactory.Config config = requestRateLimiterGatewayFilterFactory.newConfig();
config.setRateLimiter(redisLimiterUser).setKeyResolver(hostNameResolver).setStatusCode(HttpStatus.BAD_GATEWAY);
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route(r -> r.path("/my/**")
.filters(f -> f.stripPrefix(0))
.uri("lb://SERVER-FI")
.filter(requestRateLimiterGatewayFilterFactory.apply(config))
.filter(webLoginFilter)
.filter(cookieTokenFilter)
.filter(oAuthFilter)
.filter(authorizationFilter)
)
.build();
return routes.build();
}
上面的配置中filters方法内部其实是可以配置限流,而且还可以同时配置filter,但会出现一个奇怪的bug,当某一个filter被阻塞时,其他请求会强行等待,这个是真无语,而且也没有相关介绍
错误配置方法:
@Bean
@Order
public RouteLocator customRouteLocator(RouteLocatorBuilder builder,
IpFilter ipFilter,
AuthFilter authFilter) {
RequestRateLimiterGatewayFilterFactory.Config config = requestRateLimiterGatewayFilterFactory.newConfig();
config.setRateLimiter(redisLimiterUser).setKeyResolver(hostNameResolver).setStatusCode(HttpStatus.BAD_GATEWAY);
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route(r -> r.path("/my/**")
.filters(
f ->f.stripPrefix(0).requestRateLimiter(c -> {
c.setKeyResolver(hostNameResolver);
c.setRateLimiter(redisLimiterUser);
c.setStatusCode(HttpStatus.BAD_GATEWAY);
})
.filter(webLoginFilter)
.filter(cookieTokenFilter)
.filter(oAuthFilter)
.filter(authorizationFilter)
)
.uri("lb://SERVER-FI")
)
.build();
return routes.build();
}
上面的配置可以正常启动,而且在开发及测试中基本没啥问题,但是当你在filter()对应的任意filter实现类中加入睡眠,就会发现其他的请求必须要等待filter完成才能继续路由,简单来说请求会卡死。
发现filters中接收的参数是Function<GatewayFilterSpec, UriSpec> fn,java8的lambda表达式,
而fulter中接收的参数是GatewayFilter gatewayFilter
上面的错误写法应该和GatewayFilterSpec类有关,但是没看过gateway源码,网上也没有任何介绍,只能说最好用filter去装载gatewayFilter