这是我参与8月更文挑战的第17天
简介
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关.
Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:反向代理、安全,监控/埋点,和限流等。
gateway三大核心概念
- Route(路由) :这个是网管的基本构建块。它由一个id,一个目标url,一组断言和一组过滤器定义。如果断言为真,则路由匹配,反之,则不匹配
- Predicate(断言) :输入类型是一个ServerWebExchange。我们可以使用它来匹配来自Http的请求的任何内容。
- 过滤器(filter) : Gateway中的Filter分为两种类型的filter,分别是Gateway Filter和Golabl Filter 。过滤器将会对请求和响应进行修改处理
动态路由
将gateway注册进eruka
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
修改yml 需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。 lb://serviceName(微服务名称)是springcloud gateway在微服务中自动为我们创建的负载均衡uri。
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-provider-service #匹配后提供服务的路由地址,lb后跟提供服务的微服务的名,不要写错
predicates:
- Path=/payment/get/** #断言,路径相匹配的进行路由
- id: payment_routh2 #payment_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-provider-service #匹配后提供服务的路由地址,lb后跟提供服务的微服务的名,不要写错
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
filter过滤链
分为两种过滤器,一种是GatewayFilter(单个路由过滤器)。另一种是GlobalFilter(对所有路由进行拦截)
重写一个GatewayFilter:
1、实现 GatewayFilterFactory 或者继承 AbstractGatewayFilterFactory<C> 类
2、继承AbstractGatewayFilterFactory<C> 类时,构造方法中需要调用 super(C.class)
3、重写 shortcutFieldOrder方法,定义配置文件中字段的位置
4、编写的过滤器类必须要以 GatewayFilterFactory结尾
5、自定义过滤器的名字为,GatewayFilterFactory前面的字符,比如 TokenGatewayFilterFactory,那么过滤器名字是 Token
5、功能实现:过滤器实现,从请求中获取一个参数的值,打印出来
java中写法: @Component @Slf4j public class TokenGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenGatewayFilterFactory.Config> {
public TokenGatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Lists.newArrayList("tokenName");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
log.info("每次路由匹配到会执行");
String tokenName = config.getTokenName();
log.info("从配置文件中获取到的 tokenName 的值=[{}].", tokenName);
String value = exchange.getRequest().getQueryParams().getFirst(tokenName);
log.info("从请求中获取到的token value 是:[{}]", value);
return chain.filter(exchange);
};
}
配置文件中的写法 ,自定义过滤器的名字为,GatewayFilterFactory前面的字符,比如 TokenGatewayFilterFactory,那么过滤器名字是 Token
spring:
cloud:
gateway:
routes:
- id: product-provider-01
uri: lb://product-provider
predicates:
- Path=/product/findOne
filters:
- Token=gateway-token