接上文Spring Cloud Gateway教程[一]:Gateway与Eureka整合,我们来继续学习Gateway。
相关术语
Route(路由):路由是gateway的基础构建块。由一个ID,一个目标URL,一组断言和一组过滤器定义。如果断言为真,则匹配路由。
Predicate(断言):就是java8的Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
Filter(过滤器):这是
org.springframework.cloud.gateway.filter.GatewayFilter
的实例,我们可以使用它修改请求和响应。
工作流程

客户端向Gateway 发出请求,如果 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
路由断言工厂
Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates 工厂,这些 Predicates 工厂通过不同的 HTTP 请求参数来匹配。多个 Predicates 工厂可以组合使用,组合方式是逻辑与。

AfterRoutePredicateFactory: 请求时间在配置的时间之后才转发
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2019-08-21T06:06:06+08:00[Asia/Shanghai]
这个路由在2019-08-21T06:06:06之后可匹配任何请求
BeforeRoutePredicateFactory: 与AfterRoutePredicateFactory正好相反,请求发生在配置的时间之前才转发
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
BetweenRoutePredicateFactory: 需要配置开始时间与结束时间,请求必须在两个时间之间才转发
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
CookieRoutePredicateFactory:通过cookie匹配,接受两个参数:cookie名和正则表达式。请求必须包含指定的cookie,并且值与正则表达式匹配。
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p
对于这个路由一下请求才可转发:
curl http://localhost:8080 --cookie "chocolate=ch_p"
HeaderRoutePredicateFactory: 与cookie类似,也是接受两个参数:header的名称与value的正则表达式。请求需含有指定的header,值必须与指定的正则匹配。
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+
这个路由以下请求可生效:
curl http://localhost:8080 -H "X-Request-Id:666666"
HostRoutePredicateFactory: 通过host匹配,其接受一组域名列表,用","分割。通过请求参数中的主机地址进行匹配。
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org
如果请求头中包含Host,并且其值匹配 **.somehost.org,**.anotherhost.or
g即可转发, 如:
curl http://localhost:8080 -H "Host:a.somehost.org"
MethodRoutePredicateFactory: 通过请求方法匹配,下面这个例子中get请求会转发。
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET
PathRoutePredicateFactory: 通过请求路径匹配,其接受一个匹配路径的参数来判断是否转发。
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Path=/foo/{segment},/bar/{segment}
如果请求路径满足给定的规则,会进行转发,如: foo/1、/foo/a、/bar/baz
QueryRoutePredicateFactory: 根据请求参数转发,输入是请求参数与其值的正则表达式,可以只有参数,没有值的正则。只有参数名一致且值满足正则匹配才可以。
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=baz#- Query=foo, ba.
RemoteAddrRoutePredicateFactory: 根据请求IP地址进行路由。
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24
WeightRoutePredicateFactory:根据权重进行路由,其接受两个参数:分组id与权重。对于每个分组都会计算权重进行路由。
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2
这个路由把大约80%的请求发送给https://weighthigh.org,20%发送给
https://weightlow.org
组合路由:以上规则均和自由组合在一起使用,但一个请求需要同时满足这个Predicate才可以被匹配。
spring:cloud:gateway:routes:- id: host_foo_path_headers_to_httpbinuri: http://ityouknow.compredicates:- Host=**.foo.org- Path=/headers- Method=GET- Header=X-Request-Id, \d+- Query=foo, ba.- Query=baz- Cookie=chocolate, ch.p- After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
总结
通过以上学习发现Gateway的路由断言配置非常的灵活多样,可根据不同需求进行路由转发,也可组合使用。
参考资料
https://cloud.spring.io/spring-cloud-gateway/reference/html/
http://www.ityouknow.com/springcloud/2018/12/12/spring-cloud-gateway-start.html




