SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
GateWay特点Spring在2017年下半年迎来了Webflux,Webflux的出现填补了Spring在响应式编程上的空白,Webflux的响应式编程不仅仅是编程风格的改变,而且对于一系列的著名框架,都提供了响应式访问的开发包,比如Netty、Redis等等。
SpringCloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
Springcloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。
Webflux我们知道传统的Web框架,比如说:struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor线程模型的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上,因此它的运行环境的可选择行要比传统web框架多的多。
根据官方的说法,webflux主要在如下两方面体现出独有的优势:
- 非阻塞式: 其实在servlet3.1提供了非阻塞的API,WebFlux提供了一种比其更完美的解决方案。使用非阻塞的方式可以利用较小的线程或硬件资源来处理并发进而提高其可伸缩性
- 函数式编程端点: 老生常谈的编程方式了,Spring5必须让你使用java8,那么函数式编程就是java8重要的特点之一,而WebFlux支持函数式编程来定义路由端点处理请求。
SpringCloud Gateway的路由转发有如下的2中方式:但是规则是一样的.所以了解规则了,无论用什么方式都是可以的
- yml配置文件中设置
- Bean实例中设置
gateWay的主要功能之一是转发请求,转发规则的定义主要包含三个部分
- Route(路由): 路由是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发
- Predicate(谓语、断言): 路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式
- Filter(过滤器): 过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容
其实重点还是Predicate,SpringCloud GateWay默认提供了很多路由规则给我们使用(换句话说我们也可以自己自定义路由规则cuiyaonan2000@163.com)
- id相当于给规则设置个唯一标识
- uri表示满足断言后转发的地址,同时也可以是eureka中的服务名称,使用lb:服务名称来进行转发。
- order表示规则优先级,数字越小优先级越高
- predicates是判断请求是否满足该规则先决条件
Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。(如下所示只要包含smile的请求参数key,注意不是值中包含smile,就符合规则)
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
-Query=smile
如下的表示 key必须为smile,值必须是pu开头的请求才能满足规则
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
-Query=smile,pu.
Header
一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。(如下所示head头中需要包含X-Request-Id,值必须满足正则表达式)
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- Header=X-Request-Id, \d+
Cookie
可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- Cookie=sessionId, test
Host
接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- Host=**.baidu.com
Method
只有1个参数???或者多个参数???
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- Method=GET
Path
1个参数,是否可以用逗号分隔成多个地址进行匹配?????
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
-Path=/cuiyaonan2000/{segment}
Ip
Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- RemoteAddr=192.168.1.1/24
组合使用
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
一个请求满足多个路由的断言条件时,请求只会被首个成功匹配的路由ID转发
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: cuiyaonan2000_id
uri: https://www.baidu.com
order: 0
predicates:
- Host=**.cuiyaonan2000.org
- Path=/headers
- Method=GET
- Header=X-Request-Id, \d+
- Query=foo, ba.
- Query=baz
- Cookie=chocolate, ch.p
Filter
Spring-Cloud-Gateway基于过滤器实现,同zuul类似,有pre和post两种方式的filter,分别处理前置逻辑和后置逻辑。客户端的请求先经过pre类型的filter,然后将请求转发到具体的业务服务,收到业务服务的响应之后,再经过post类型的filter处理,最后返回响应到客户端。
过滤器执行流程如下,order越大,优先级越低.所有的过滤器都会顺序执行.
规则举例说明PrefixPath- PrefixPath=/app在请求路径前加上appRewritePath- RewritePath=/test, /app/test访问localhost:9022/test,请求会转发到localhost:8001/app/testSetPath- SetPath=/app/{path}通过模板设置路径,转发的规则时会在路径前增加app,{path}表示原请求路径RedirectTo重定向RemoveRequestHeader去掉某个请求头信息 PrefixPath对所有的请求路径添加前缀:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
RedirectTo
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
RemoveRequestHeader
去掉某个请求头信息:
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
RemoveResponseHeader
去掉某个回执头信息:
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Request-Foo
RemoveRequestParameter
去掉某个请求参数信息:
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
RewritePath
改写路径:/where/... 改成 test/...
spring:
cloud:
gateway:
routes:
- id: rewrite_filter
uri: http://localhost:8081
predicates:
- Path=/test/**
filters:
- RewritePath=/where(?/?.*), /test(?/?.*)
SetPath
设置请求路径,与RewritePath类似。
如/red/blue的请求被转发到/blue。
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
SetRequestHeader
设置请求头信息。
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
SetStatus
设置回执状态码。
spring:
cloud:
gateway:
routes:
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
StripPrefix
跳过指定路径: 请求/name/blue/red会转发到/red。
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
RequestSize
请求大小。
超过5M的请求会返回413错误。
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
Default-filters
对所有请求添加过滤器。
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
GateWay 的熔断
此熔断与微服务Feign的熔断是一个意思,但是应用场景不一样.
- 微服务的熔断: 针对的是微服务之间的相互调用的熔断处理
- GateWay的熔断: 针对的是C端(即外部调用的)的的调用熔断.