常用的路由断言(Predicate)
Gateway支持多种方式的Predicate。
1. AfterRoutePredicateFactory
在设置的时区时间之后网关才能访问。
predicates:
- After=2021-03-06T18:32:59.640+08:00[Asia/Shanghai]
2. BeforeRoutePredicateFactory
在设置的时区时间之前网关可以访问。
predicates:
- Before=2021-03-06T18:32:59.640+08:00[Asia/Shanghai]
3. BetweenRoutePredicateFactory
在设置的两个时区时间以内网关可以访问
predicates:
- Before=2021-03-06T18:32:59.640+08:00[Asia/Shanghai], 2021-03-07T18:32:59.640+08:00[Asia/Shanghai]
4. CookieRoutePredicateFactory
只有当访问携带的Cookie中的key和value与断言中设置的一样,网关才能访问
predicates:
- Cookie=username, John
断言中还可以使用正则表达式动态匹配Cookie中的value,正则表达式匹配成功,网关才能访问
predicates:
- Cookie=username, [A-Za-z0-9]+
5. HeaderRoutePredicateFactory
断言使用正则表达式匹配请求头中某一个属性的value,正则表达式匹配成功,网关才能访问
predicates:
- Header=X-Request-Id, \d+
6. MethodRoutePredicateFactory
发送的指定请求方式相同,网关才能访问
predicates:
- Method=GET, POST
常用的Filter
1. 说明
当我们有很多个服务时,比如下图中的用户服务、订单服务、商品服务等服务。客户端请求各个服务的API时,每个服务都需要做相同的事情,比如鉴权、限流、日志输出等。
添加了Fliter之后,API网关就可以统一进行鉴权、限流、日志输出。
2. 内置过滤器
Spring Cloud Gateway虽然提供了很多内置过滤器,但是在实际开发场景中并不多见,因此本文不加入内置过滤器的内容。
3. 自定义过滤器
-
网关模块创建filter包。
-
网关模块创建自定义Filter类
// 自定义全局Filter @Configuration @Slf4j public class CustomGlobalFilter implements GlobalFilter, Ordered { /** * Filter处理方法 * @param exchange Spring WebFlux框架封装的交换机,其中包含Request和Response * @param chain filterChain * @return Mono<Void> */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("进入自定义Filter"); String username = exchange.getRequest().getQueryParams().get("username").get(0); if ("John".equals(username)) { log.info("身份验证成功"); // 放行请求 return chain.filter(exchange); } log.info("身份验证失败,拒绝访问"); return exchange.getResponse().setComplete(); } /** * 通过返回值设置当前Filter的优先级 * @return 范围:-1 ~ ∞, 返回值越大优先级越低 */ @Override public int getOrder() { return 0; } }
Gateway工作原理
- Gateway Handler Mapping:解析请求路径。
- Gateway Web Handler:通过断言匹配相应服务。
- Filters:过滤器相关处理。
- Proxied Service:各个微服务。
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。此处理程序通过特定于请求的筛选器链运行请求。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前和之后运行逻辑。执行所有"pre"过滤器逻辑,然后发出代理请求。发出代理请求后,运行"post"过滤器逻辑。