SpringCloud Alibaba 2021微服务实战十二 Springcloud alibaba整合gateway 之 过滤器讲解

过滤器(Filter)

GatewayFilter允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用域是特定的路由。 Spring Cloud Gateway包括许多内置的GatewayFilter工厂。
GlobalFilter接口具有与GatewayFilter相同的签名。这些是特殊过滤器,有条件地应用于所有路由
https://docs.spring.io/spring-cloud-gateway/docs/3.0.2/reference/html/#gatewayfilter-factories

这个文档中,有两种Filter(GatewayFilter和GlobalFilter)

image.png

GatewayFilter官网给出了这么31个过滤器工厂(工厂就是产生对象的,也就是相当于31个过滤器),
GlobalFilter官网给出了这么10个过滤器工厂(工厂就是产生对象的,也就是相当于10个过滤器):

image.pngimage.pngimage.png

生命周期
Spring Cloud Gateway同zuul类似,有“pre”和“post”两种方式的filter。客户端的请求先经过“pre”类型的filter,然后将请求转发到具体的业务服务,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。

与zuul不同的是,filter除了分为“pre”和“post”两种方式的filter外,在Spring Cloud Gateway中,filter从作用范围可分为另外两种,一种是针对于单个路由的gateway filter,它在配置文件中的写法同predict类似;另外一种是针对于所有路由的global gateway filer。现在从作用范围划分的维度来讲解这两种filter。

gateway filter
 

过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。过滤器可以限定作用在某些特定请求路径上。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。

GatewayFilter工厂同上一篇介绍的Predicate工厂类似,都是在配置文件application.yml中配置,遵循了约定大于配置的思想,只需要在配置文件配置GatewayFilter Factory的名称,而不需要写全部的类名,比如AddRequestHeaderGatewayFilterFactory只需要在配置文件中写AddRequestHeader,而不是全部类名。在配置文件中配置的GatewayFilter Factory最终都会相应的过滤器工厂类处理。

Spring Cloud Gateway 内置的过滤器工厂一览表如下:
在这里插入图片描述

 

 

怎么用呢?
就像是断言(Predicate)一样,在spring.cloud.gateway.routes下面添加就好了,和iduri同级。
 

现在挑几个常见的过滤器工厂来讲解,每一个过滤器工厂在官方文档都给出了详细的使用案例,如果不清楚的还可以在org.springframework.cloud.gateway.filter.factory看每一个过滤器工厂的源码。

AddRequestHeader GatewayFilter Factory

server:
  port: 9090
​
spring:
  application:
    name: @artifactId@
  cloud:
    nacos:
      discovery:
        server-addr: 172.17.169.81:8848
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          #uri: http://localhost:8070/payment/get/31
          uri: lb://payment-service
          #uri: http://localhost:8070
          
          predicates:
            #- Path=/payment/get/** # 断言,路径相匹配的进行路由
            - After=2021-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2022-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,liu
            #- Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性,并且值为正数
            #- Host=**.baidu.com
            #- Method=GET
            #- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
          # 过滤
          filters:
            - AddRequestHeader=X-Request-Foo, liu
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        #- id: payment_route2
         # uri: http://localhost:8001
         # predicates:
            #Path=/payment/lb/** #断言,路径相匹配的进行路由
​
​有一个filter为AddRequestHeaderGatewayFilterFactory(约定写成AddRequestHeader),AddRequestHeader过滤器工厂会在请求头加上一对请求头,名称为X-Request-Foo,值为liu。为了验证AddRequestHeaderGatewayFilterFactory是怎么样工作的,查看它的源码,AddRequestHeaderGatewayFilterFactory的源码如下:


public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

	@Override
	public GatewayFilter apply(NameValueConfig config) {
		return (exchange, chain) -> {
			ServerHttpRequest request = exchange.getRequest().mutate()
					.header(config.getName(), config.getValue())
					.build();

			return chain.filter(exchange.mutate().request(request).build());
		};
    }

}

由上面的代码可知,根据旧的ServerHttpRequest创建新的 ServerHttpRequest ,在新的ServerHttpRequest加了一个请求头,然后创建新的 ServerWebExchange ,提交过滤器链继续过滤。

 

跟AddRequestHeader过滤器工厂类似的还有AddResponseHeader过滤器工厂,在此就不再重复。

 

RewritePath GatewayFilter Factory

在Nginx服务启中有一个非常强大的功能就是重写路径,Spring Cloud Gateway默认也提供了这样的功能,这个功能是Zuul没有的。在配置文件中加上以下的配置:

server:
  port: 9090

spring:
  application:
    name: @artifactId@
  cloud:
    nacos:
      discovery:
        server-addr: 172.17.169.81:8848
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          #uri: http://localhost:8070/payment/get/31
          uri: lb://payment-service
          #uri: http://localhost:8070

          predicates:
            #- Path=/payment/get/** # 断言,路径相匹配的进行路由
            - After=2021-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2022-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,liu
            #- Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性,并且值为正数
            #- Host=**.baidu.com
            #- Method=GET
            #- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
          # 过滤

          filters:
            - RewritePath=/api/(?<segment>.*), /$\{segment}
            #- AddRequestHeader=X-Request-red, blue
        #- id: payment_route2
         # uri: http://localhost:8001
         # predicates:
            #Path=/payment/lb/** #断言,路径相匹配的进行路由

上面的配置中,所有的/api/**开始的路径都会命中配置的router,并执行过滤器的逻辑,在本案例中配置了RewritePath过滤器工厂,此工厂将/api/(?.*)重写为{segment},然后转发。比如在网页上请求http://localhost:9090/api/payment/get/31,此时会将请求转发到http://localhost:8070的页面

平时我们最常用的是自定义过滤器,所以这里就不做详细描述,官方文档中有详细实现配置,有兴趣的小伙伴可以访问官网查看:

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories

StripPrefix前缀网关过滤器工厂采用一个参数StripPrefix。

StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。

 

spring:
  cloud:
    gateway:
      routes:
      - id: aaaaa-bbbb
        uri: lb://aaaaa-bbbb
        predicates:
        - Path=/aa/**
        filters:
        - StripPrefix=2

 

 

当通过网关向/name/bar/foo发出请求时,去除两层相当于对nameservice的请求将类似于lb://aaaaa-bbbb/foo。

 

网关的断言结合过滤器,实现路由调转,理解后很容易应用,总体上应用上很容易!

微服务部署图可以加深路由的理解

 

两讲讲解了断言及自带过滤器,但最常用的还是自定义过滤器,下面重点讲解自定义过滤器!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值