本文是对这段时间学习的整理归纳,方便后续翻阅回忆,每个点对应的实践工程代码已上传 GitHub
SpringCloudGateway
SpringCloudGateway 是 SpringCloud 的第二代网关,基于 Netty、Reactor、WebFlux构建,将会取代第一代的网关 Zuul(性能相比提升了1.6倍)
注意:SpringCloudGateway 无法在 servlet 容器(如 tomcat)下工作,也无法打成 war 包,且只支持 SpringBoot 2.0+。
核心概念
- Route(路由):转发规则,包含ID、目标URL、Predicate集合以及Filter集合。
- Predicate(断言):匹配路由的条件,实现方式是 java.util.function.Predicate 的函数接口。
- Filter(过滤器):对请求和响应的自定义修改。
工作原理
- 流程图 官网地址
三种 uri 路由方式
- 路由到指定URL
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://www.baidu.com
predicates:
- Path=/shares/**
filters:
- AddRequestHeader=x-oysq, test1
- 路由到 websocket
uri: ws://1.1.1.1:1111
- 路由到服务发现组件上的微服务
- gateway能识别的微服务明必须符合正则:
[a-zA-Z]([a-zA-Z]|\\d|\\+|\\.|-)*:.*
- 注意:该正则不含有下划线
_
uri: lb://content-center
两种匹配方式
- 通配:访问 http://{gateway_url}/** 会转发到 http://www.baidu.com/**
uri: http://www.baidu.com
- 精确匹配:访问 http://{gateway_url}/abc/123 会转发到 http://www.baidu.com/abc/123
uri: http://www.baidu.com/abc/123
十种内置的谓词工厂
注意:存在多个断言时,匹配优先级是从上到下,并不是根据匹配程度。
技巧:时间可使用 System.out.println(ZonedDateTime.now()); 打印,然后即可看到时区。例如:2021-09-19T17:21:23.243+08:00[Asia/Shanghai]
谓词 |
---|
After |
Before |
Between |
Cookie |
Header |
Host |
Method |
Path |
Query |
RemoteAddr |
自定义谓词工厂
自定义谓词工厂的类名必须是:谓词+RoutePredicateFactory
例如自定义谓词 Contain, 则类名必须是 ContainRoutePredicateFactory
- 方法概述:自定义谓词工厂类,继承
AbstractRoutePredicateFactory
抽象类,实现shortcutFieldOrder()
接口来将yml文件的谓词与配置类的字段一一对应起来,实现apply()
方法返回一个 Predicate 函数式接口进行判断是否断言成功,有点像策略模式 - 详细信息看 oysq/gateway 项目里面的demo
26种内置过滤器工厂
# 举例:为请求添加 header 头 x-oysq, 值为 test1
filters:
- AddRequestHeader=x-oysq, test1
自定义过滤器工厂
自定义过滤器工厂的类名必须是:过滤器名+GatewayFilterFactory
例如自定义过滤器 PreLog, 则类名必须是 PreLogGatewayFilterFactory
- 过滤器声明周期
- pre:Gateway 转发请求之前
- post:Gateway 转发请求之后
- 核心 API
- exchange.getRequest().mutate().xxx //修改 request
- exchange.mutate().xxx //修改 exchange
- chain.filter(exchange) //传递给下一个过滤器
- exchange.getResponse() //修改响应
- 实现方式
注意:两种实现的方式,最后在yml配置文件里面的配置方式是不一样的
- 继承
AbstractGatewayFilterFactory
- 继承
AbstractNameValueGatewayFilterFactory
(内部继承了上一种方式,是上一种方式的简化版)
局部过滤器的执行顺序
一个Route中可以配置多条局部过滤器,从上到下的执行顺序从1开始递增。
若配置了默认过滤器
default-filters
,则先执行默认的1,再执行Route中的1,然后再执行默认的2,以此类推。自定义过滤器工厂可以通过返回
OrderedGatewayFilter
来改变Order
顺序
全局过滤器
全局过滤器有9种,并且可以通过 @Order 的方式指定执行顺序,数字越小,优先级越高。
gateway 监控端点
- GET http://localhost:8040/actuator/gateway/routes // 查看所有路由
- POST http://localhost:8040/actuator/gateway/refresh // 刷新路由缓存
此外还支持动态添加、修改、删除路由,查看全局路由等等
其他
SpringCloudGateway
默认使用Hystrix
进行容错,也可以改为Sentinel
,但是要1.6
版本开始的Sentinel
才支持。此外,还可以集成redis
进行集群限流(基于令牌桶算法的实现)。
SpringCloudGateway
默认集成了Ribbon
,因此自带了对lb
微服务的负载均衡。