Spring Cloud Gateway入门
Spring Cloud Gateway是Spring官方基于Spring5.0、Spring Boot2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效且统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅仅提供统一的路由方式,并且还基于Filter链的方式提供了网关基本功能,例如:安全、监控/埋点、限流等。
Spring Cloud Gateway中有3个比较重要的概念:
- 路由:路由是网关最基础的部分,路由信息由一个ID、一个目的URL、一组断言工程和一组Filter组成。如果路由断言为真,则说明请求的url和配置的路由匹配
- 断言:Java 8 中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring 5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自于HTTP Request中的任何信息,比如请求头和参数等。
- 过滤器:一个标准的Spring webFilter。Spring Cloud Gateway中的Filter分为两种类型的Filter, 分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理。
Spring Cloud Gateway的核心处理流程如下图所示,Gateway的客户端会向Spring Cloud Gateway发起请求,请求首先被HttpWebHandlerAdapter进行提取组装成网关的上下文,然后网关的上下文会传递到DispatcherHandler。DispatcherHandler是所有请求的分发处理器,DispatcherHandler主要负责分发请求对应的处理器,比如将请求分发到对应RoutePredicateHandlerMapping(路由断言处理映射器)。路由断言处理映射器主要用于路由的查找,以及找到路由后返回对应的FilteringWebHandler。FilteringWebHandler主要负责组装Filter链表并调用Filter执行一系列的Filter处理,然后把请求转到后端对应的代理服务器处理,处理完毕之后,将Response返回到Gateway客户端。
简单的Gateway例子
新建一个maven项目first-gateway,其pom依赖为:
1 | <parent> |
然后新建一个启动类,代码如下:
1 |
|
上图自定义了一个路由转发规则,将访问/jd的请求,定向到http://jd.com:80上
路由断言
Spring Cloud Gateway的路由匹配功能时以Spring WebFlux中的Handler Mapping为基础实现的。Spring Cloud Gateway也是由许多的路由断言工厂组成的。当Http Request请求进入Spring Cloud Gateway的时候,网关中的路由断言工厂会根据配置的路由规则,对Http Request请求进行断言匹配。匹配成功则进行下一步处理,否则断言失败直接返回错误信息。
After路由断言工厂
After Route Predicate Factory中会取一个UTC时间格式的参数,当请求进来的当前时间再配置的UTC时间之后,则会成功匹配,否则不能成功匹配。
将上个例子中的启动类改为:
1 |
|
先在第8行的after中传入minusTIme,表示,在minusTime之后进来的所有请求都可以通过。而minusTime就是当前时间往前移动一个小时。
在浏览器中访问http://localhost:8080,就可以看到请求被定向到baidu.com
而如果把minusTime改为plusTime,意为在当前时间一个小时候进来的请求才能允许通过。在浏览器中再次访问http://localhost:8080,就可以看到请求被拒绝了。
Before路由断言工厂
Before路由断言工厂会取一个UTC时间格式的时间参数,当请求进来的当前时间再路由断言工厂之前会成功匹配,否则不能成功匹配。
1 |
|
首先在befor方法中传入minusTime,表示在一小时之前的请求,才能通过,接着传入plusTime,表示只要在当前时间后一个小时前的所有请求都可以通过。
Between路由断言工厂
Between路由断言工厂会取两个UTC时间格式的时间参数,当请求进来的当前时间在配置的UTC时间工厂之间会成功匹配,否则不能成功匹配。
1 |
|
Cookie路由断言工厂
Cookie路由断言工厂会取两个参数-cookie名称对应的key和value。当请求中携带的cooke和Cookied断言工厂配置的cookie一致,则路由匹配成功,否则匹配不成功。
1 |
|
Header路由断言工厂
Header路由断言工厂用于根据配置的路由header信息进行断言匹配路由,匹配成功进行转发,否则不进行转发。
1 |
|
Host路由断言工厂
Host路由断言工厂根据配置的Host,对请求中的Host进行断言处理,断言成功则进行路由转发,否则不转发。
1 |
|
Method路由断言工厂
Method路由断言工厂会根据路由信息配置的method对请求方法是Get或者Post等进行断言匹配,匹配成功则进行转发,否则处理失败。
1 |
|
Query路由断言工厂
Query路由断言工厂会从请求中获取两个参数,将请求中参数和Query断言路由中的配置进行匹配。
比如 http://localhost:8080?foo=bar中的foo=bar和r.query(“foo”, “bar”)配置一致则转发成功,否则转发失败。
1 |
|
RemoteAddr路由断言工厂
RemoteAddr路由断言工厂配置一个IPv4或IPv6网段的字符串或者IP。当请求IP地址在网段之内或者和配置的IP相同,则表示成功匹配,成功转发,否则不能转发.
1 |
|
内置Filter
Spring Cloud Gateway中内置很多的路由过滤工厂,也可以根据实际应用场景定制自己的路由过滤器工厂。路由过滤器允许以某种方式修改请求进来的http请求或返回http响应。路由过滤器主要作用域需要处理的特定路由。Spring Cloud Gateway提供了很多种类的过滤器工厂,过滤器的实现类将近二十多个。总的来说,可以分为七类:Header、Parameter、Path、Status、Redirect跳转。Hystrix熔断和RateLimiter。
AddRequestHeader过滤器工厂
AddRequestHeader过滤器工厂用于对匹配上的请求加上header。
1 |
|
AddRequestParameter过滤器
AddRequestParameter过滤器作用是对匹配上的请求路由添加请求参数。
1 |
|
RewritePath过滤器
Spring Cloud Gateway可以使用RewritePath替换Zuul的StripPrefix功能,而且功能更 强大。在Zuul中使用如下配置:
1 | zuul: |
说明:这里的stripPrefix默认为true,也就是所有的/demo/xxx的请求转发给http://demo.com/xxxx,去除demo前缀。
Spring Cloud Gateway实现类似的功能,使用的是RewritePath过滤器工厂。
1 |
|
AddResponseHeader过滤器
AddResponseHeader过滤器工厂的作用是对从网关返回的响应添加Header。
1 |
|
StripPrefix过滤器
StripPrefix过滤器工厂是一个对针对请求url前缀进行处理的filter工厂,用于去除前缀。
1 |
|
stripPrefix(int)的入参是一个整型,表示要剥离的前缀层数。比如,/1/2/test会被剥离成/test
Retry过滤器
网关作为所有请求流量的入口,网关对路由进行协议适配和协议转发处理的过程中,如果出现异常或网络抖动,为了保证后端服务请求的高可用,一般处理方式会对网络请求进行重试。
1 |
|
上面代码表示设置重试次数为两次,当代理服务调用失败时设置返回的状态码为500.