目录
什么是Spring Cloud Gateway
2. Spring Cloud Gateway快速开始
2.1 环境搭建
2.2 路由断言工厂(Route Predicate Factories)配置
2.2.2 Cookie匹配
编辑
2.2.3 Header匹配
2.2.4 路径匹配
2.2.5 自定义路由断言工厂
2.3 过滤器工厂( GatewayFilter Factories)配置
2.3.2 添加请求参数
2.3.3 为匹配的路由统一添加前缀
2.4 全局过滤器(Global Filters)配置
2.4.1 LoadBalancerClientFilter
2.4.2 自定义全局过滤器
网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
官网文档:Spring Cloud Gatewayhttps://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
1.1 核心概念
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。
Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。
SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。
1.2 工作原理
Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的区别就是 Gateway 的 Filter 只有 pre 和 post 两种。
客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑。
1) 引入依赖
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2) 编写yml配置文件
server:
port: 8888
spring:
application:
name: service-gateway
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true
# 是否开启网关
enabled: true
3)测试
Spring Cloud Gateway
网关启动日志:
2.2.1 时间匹配
可以用在限时抢购的一些场景中。
设置时间之前发起请求:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2022-11-21T16:01:07.783+08:00[Asia/Shanghai]
discovery:
locator:
# 默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
enabled: false
# 是否开启网关
enabled: true
gateway:
routes:
-id: servicea-route
uri: http://localhost:8010 #目标微服务的请求地址和端口
predicates:
- Cookie=username, sb
spring:
cloud:
gateway:
#设置路由:路由id、路由到微服务的uri、断言
routes:
-id: servicea-route
uri: http://localhost:8010 #目标微服务的请求地址和端口
predicates:
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
#- Header=X-Request-Id, \d+
server:
port: 8888
spring:
application:
name: servicea-gateway
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: servicea-route
uri: http://localhost:8010 #目标微服务的请求地址和端口
predicates:
# 匹配在指定的日期时间之后发生的请求 入参是ZonedDateTime类型
# - After=2023-01-31T22:22:07.783+08:00[Asia/Shanghai]
# - Cookie=username, sb
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
# - Header=X-Request-Id, \d+
- Path=/service-a/** #Path路径匹配
discovery:
locator:
# 默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
enabled: false
# 是否开启网关
enabled: true
自定义路由断言工厂需要继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
注意: 命名需要以 RoutePredicateFactory 结尾
1、类必须是Spring组件 Bean
2、类必须加上RoutePredicateFactory作为结尾
3、类必须继承AbstractRoutePredicateFactory
4、类必须声明静态内部类,声明属性来接收配置文件中对应的断言的信息
5、需要结合shortcutFieldOrder进行绑定
6、通过apply进行逻辑判断,true:配置成功,false:配置失败
server:
port: 8888
spring:
application:
name: servicea-gateway
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: servicea-route
uri: http://localhost:8010 #目标微服务的请求地址和端口
predicates:
# 匹配在指定的日期时间之后发生的请求 入参是ZonedDateTime类型
# - After=2023-01-31T22:22:07.783+08:00[Asia/Shanghai]
# - Cookie=username, sb
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
# - Header=X-Request-Id, \d+
- Path=/service-a/** #Path路径匹配
#自定义断言工厂
- CheckAuth=sb
discovery:
locator:
# 默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
enabled: false
# 是否开启网关
enabled: true
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory {
public CheckAuthRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
log.info("调用CheckAuthRoutePredicateFactory:{}",config.getName());
if (config.getName().equals("sb")){
return true;
}
return false;
}
};
}
/**
* 快捷配置
* @return
*/
@Override
public List shortcutFieldOrder() {
return Collections.singletonList("name");
}
public static class Config {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
SpringCloudGateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factorieshttps://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
gateway:
routes:
- id: servicea-route
uri: http://localhost:8010 #目标微服务的请求地址和端口
predicates:
# 匹配在指定的日期时间之后发生的请求 入参是ZonedDateTime类型
# - After=2023-01-31T22:22:07.783+08:00[Asia/Shanghai]
# - Cookie=username, sb
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
# - Header=X-Request-Id, \d+
- Path=/service-a/** #Path路径匹配
#自定义断言工厂
# - CheckAuth=sb
#配置过滤器工厂
filters:
- AddRequestHeader=X-Request-color, red #添加请求头
discovery:
locator:
# 默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
enabled: false
# 是否开启网关
enabled: true
@GetMapping("/testgateway")
public String testGateway(HttpServletRequest request) throws Exception {
log.info("gateWay获取请求头X-Request-color:"
+request.getHeader("X-Request-color"));
return "success";
}
@GetMapping("/testgateway2")
public String testGateway(@RequestHeader("X-Request-color") String color) throws Exception {
log.info("gateWay获取请求头X-Request-color:"+color);
return "success";
}
等。。。。