spring cloud gateway核心概念之断言和过滤器

核心概念

  • 路由(Route):路由是网关的基本构件。它由ID、目标URI、一组断言和一组过滤器组成。如果断言为真,则匹配该路由。gateway使用类RouteDefinition表示路由定义。
  • 断言(Predicate):参照Java8的新特性Predicate。Predicate接受一个输入参数,返回一个布尔值结果,输入参数可以是HTTP请求的任何部分,比如报文头、参数、报文体,而且还可以将多个断言组合在一起。
  • 过滤器(Filter):可以在发送到目标URI之前或之后修改请求和响应。

1 断言

spring cloud gateway 2.2.9.RELEASE版本里面,提供了12个断言,gateway使用工厂模式创建这些断言,它们都是在断言工厂里面创建的。这些断言工厂都继承了抽象类AfterRoutePredicateFactory。下面分别介绍这些断言的作用和例子。

(1)AfterRoutePredicateFactory

该断言支持设置一个时间,转发请求时,如果在该时间之后,则断言为真。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - After=2021-09-10T00:00:00+08:00

这个断言会在东8区的2021-09-10 凌晨12点之后,将请求都转跳到http://localhost:8079。

(2)BeforeRoutePredicateFactory

与AfterRoutePredicateFactory相反,BeforeRoutePredicateFactory表示在指定的时间之前的请求都进行跳转。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Before=2021-09-10T00:00:00+08:00

这个断言会在东8区的2021-09-10 凌晨12点之前,将请求都转跳到http://localhost:8079。

(3)BetweenRoutePredicateFactory

BetweenRoutePredicateFactory接受两个时间,它表示转发在指定时间之间的请求。比如:

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Between=2021-09-01T10:00:00+08:00,2021-09-10T12:00:00+08:00 # 匹配两个时间之间

(4)MethodRoutePredicateFactory

MethodRoutePredicateFactory根据POST、GET、PUT、DELETE 等不同的HTTP方法进行判断。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Method=GET

上面例子中,所有的GET请求都会被转发。Method可以指定多个。

(5)CookieRoutePredicateFactory

CookieRoutePredicateFactory根据cookie内容进行判断。它有两个参数,一个是cookie名,另一个是value,value使用正则表达式,当cookie中含有指定的cookie名,且值符合value的正则表达式,则将转发请求。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Cookie=sessionId, test

当cookie中含有sessionId=test的内容时,转发请求。

(6)HostRoutePredicateFactory

HostRoutePredicateFactory使用一组主机列表作为判断条件。如果当前请求的报文头中含有属性“Host”,且其值在指定的主机列表里面,则将转发请求。主机列表使用Ant style匹配。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Host=**.maven.org,**.spring.org

(7)HeaderRoutePredicateFactory

HeaderRoutePredicateFactory指定了两个参数,一个header的name,一个是正则匹配的value。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Header=X-Request-Id, \d+

上述规则匹配header中存在名为X-Request-Id,内容为数字的请求。

(8)PathRoutePredicateFactory

PathRoutePredicateFactory使用Spring的PathPattern匹配请求path。PathPattern支持多种规则,可以使用类似Ant style,也可以使用正则表达式,具体的规则在PathPattern类中有详细说明。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Path=/demo/** 

上述规则匹配所有以/demo/开头的路径。

(9)WeightRoutePredicateFactory

WeightRoutePredicateFactory基于权重进行路由,配置时指定分组和权重值。下面网页对于配置规则及算法进行了详细说明:

https://www.cnblogs.com/liukaifeng/p/10055866.html

(10)RemoteAddrRoutePredicateFactory

RemoteAddrRoutePredicateFactory可以指定被请求的远程地址,当地址符合要求时,请求才会转发。可以在地址里面指定子网掩码。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - RemoteAddr=192.168.1.1/24

上述例子中,子网掩码是24,凡是请求的远程地址为192.168.1.XXX都会被转发。

(11)QueryRoutePredicateFactory

QueryRoutePredicateFactory入参也是两个参数,一个是请求参数的属性名,另一个是属性值,属性值使用正则表达式。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Query=role,ba.

(12)CloudFoundryRouteServiceRoutePredicateFactory

CloudFoundryRouteServiceRoutePredicateFactory在云计算场景下使用。它判断header里面是否有属性:X-CF-Forwarded-Url、X-CF-Proxy-Signature和X-CF-Proxy-Metadata。当header里面同时有上述三个属性时,请求才会被转发。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - CloudFoundry=XXX

CloudFoundry的值对请求转发不起作用,可以随意写任何值。

(13)组合断言

我们可以组合上面介绍的断言一起使用。比如:

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
          	- Path=/demo/** 
            - Query=role,ba.
            - After=2021-09-10T00:00:00+08:00

当所有的断言都为真时,请求才会被转发。

2 过滤器

过滤器可以修改HTTP请求的输入和输出,Spring Cloud Gateway内置了很多不同功能的过滤器。在gateway中,过滤器有两个顶级接口,这也将过滤器分为两类:

  • GatewayFilter:网关过滤器,需要通过 spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过 spring.cloud.default-filters 配置在全局,作用在所有路由上。
  • GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过 GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器。

gateway提供了很多过滤器,本文只介绍部分过滤器介绍。网关过滤器使用了工厂模式,均是由对应的工厂类创建,工厂类都实现自GatewayFilterFactory接口。

2.1 网关过滤器

(1)AddRequestHeaderGatewayFilterFactory
AddRequestHeaderGatewayFilterFactory可以在header里面增加指定的name和value。比如:


spring:  
	cloud:    
		gateway:   
        	routes: 
            - id: route-demo
              uri: http://localhost:8079   
              filters:
              - AddRequestHeader=X-Request,BAR

对被转发的请求,会在header里面额外添加属性值X-Request=Bar。
(2)AddResponseHeaderGatewayFilterFactory
AddResponseHeaderGatewayFilterFactory在请求响应的header里面添加指定的name和value。比如:

spring:  
	cloud:   
    	gateway:  
        	routes:      
        	- id: route-demo    
              uri: http://localhost:8079     
              filters:        
              - AddResponseHeader=X-Request,BAR

当收到响应后,在header里面增加属性值X-Request=Bar。
(3)RemoveRequestHeaderGatewayFilterFactory
RemoveRequestHeaderGatewayFilterFactory在header里面删除指定的name。
(4)MapRequestHeaderGatewayFilterFactory
MapRequestHeaderGatewayFilterFactory指定两个header的属性名:fromHeader和toHeader,转发请求前,过滤器将属性名从fromHeader替换为toHeader,属性值不变。
(5)RewritePathGatewayFilterFactory
RewritePathGatewayFilterFactory可以对请求路径重写。过滤器指定两个参数:regexp和replacement,两个参数都使用正则表达式,前者指定要替换的内容,后者表示被替换后的内容。

spring:
  cloud:
    gateway:
      routes:
      - id: route-demo
        uri: http://localhost:8079   
        predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo/(?<segment>.*), /$\{segment}

对于上面的例子,如果请求的路径是/foo/bar,则gateway会将请求路径改为/bar发送给下游。
(6)PrefixPathGatewayFilterFactory
该过滤器工厂为匹配的URI添加指定前缀。
(7)AddRequestParameter
该过滤器将指定参数添加请求中。
还有其他过滤器,本文不再介绍。请参见文章:

https://blog.csdn.net/abu935009066/article/details/112252692

2.2 全局过滤器

全局过滤器实现了Order接口,该接口的作用用于指定过滤器的顺序,数字越小,优先级越高。
(1)NettyWriteResponseFilter

使用Netty与请求方建立的连接将收到的代理响应写回请求端。

(2)GatewayMetricsFilter
该过滤器用于监控,提供监控指标。它统计请求成功、失败的次数,请求耗时时长等。
该过滤器需要依赖spring-boot-starter-actuator。

(3)NoLoadBalancerClientFilter

该过滤器要求目标URI的schema不能是“lb”,否则向请求方返回404。

lb表示从注册中心获取目标URL。

如果要使该过滤器失效,则需要引入Ribbon。
(4)WebClientWriteResponseFilter
使用WebClient与请求方建立的连接将收到的代理响应写回请求端。

(5)WebClientHttpRoutingFilter
使用WebClient向目标URI发送httphttps请求。不过在发送前,要先经过gateway中的其他过滤器处理,在所有的过滤器都处理完毕后,再发送请求。

(6)ForwardRoutingFilter

ForwardRoutingFilter会查看客户端请求的URI的schema是否是forward,比如:forward://localendpoint,如果是,则它会使用Spring的DispatcherHandler来处理这个请求。

(7)ForwardPathFilter

ForwardPathFilter会查看目标URI的scheme是否是forward,比如:forward://localendpoint,如果是,则它会使用Spring的DispatcherHandler来处理这个请求。

(8)RouteToRequestUrlFilter

这个过滤器用于将从request里获取的原始URL转换成Gateway转发时所使用的URL。
如果 URL 具有 scheme 前缀,例如 lb:ws://serviceid ,该 lb scheme将从URL中剥离,并放到Gateway上下文中,方便后面的过滤器使用。

(9)ReactiveLoadBalancerClientFilter
该过滤器依赖spring-cloud-starter-loadbalancer
如果原始URL或者目标URL的scheme为“lb”,比如:lb://myservice,那么ReactiveLoadBalancerClientFilter使用ReactorLoadBalancer查找myservice的服务地址列表,并且使用负载均衡算法选择合适的地址。
(10)NettyRoutingFilter

使用Netty的HttpClient向目标URI发送httphttps请求。不过在发送前,要先经过gateway中的其他过滤器处理,在所有的过滤器都处理完毕后,再发送请求。

(11)WebsocketRoutingFilter
使用WebSocketService向目标URI发送wswss请求。

3 过滤器的顺序

当请求到来时,gateway添加所有GlobalFilter实例和匹配的GatewayFilter实例到过滤器链中,通过对filter bean配置注解@Order,过滤器链会对这些过滤器实例进行排序。
Spring Cloud Gateway将过滤器的逻辑按请求执行点分为”pre”和”post”的一前一后处理,如果是高优先级的过滤器,则在”pre”逻辑中最先执行,在”post”逻辑中最后执行。

参考文章

https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值