2021年Spring Cloud Gateway中文文档详细解析(1-6章)(3.0.2版)

目录

前言

Gateway是什么

特征

1.如何包含Spring Cloud Gateway

2.关键词

3.工作原理

原理图

原理

注意

4.在配置文件中配置Predicate和Gateway Filter的两种方式

简写

完全展开

5.Route Predicate Factories

AfterRoutePredicateFactory

BeforeRoutePredicateFactory

BetweenRoutePredicateFactory

CookieRoutePredicateFactory

HeaderRoutePredicateFactory

HostRoutePredicateFactory

MethodRoutePredicateFactory

PathRoutePredicateFactory

QueryRoutePredicateFactory

ReadBodyPredicateFactory

RemoteAddrRoutePredicateFactory

WeightRoutePredicateFactory

6.GatewayFilter Factories

AddRequestHeaderGatewayFilterFactory

AddRequestParameterGatewayFilterFactory

AddResponseHeaderGatewayFilterFactory

DedupeResponseHeaderGatewayFilter

CircuitBreakerGatewayFilter

以状态码触发断路器

FallbackHeadersGatewayFilter

MapRequestHeaderGatewayFilter

PrefixPathGatewayFilter

其余文档链接


outePredicateFactory

ReadBodyPredicateFactory

RemoteAddrRoutePredicateFactory

WeightRoutePredicateFactory

6.GatewayFilter Factories

AddRequestHeaderGatewayFilterFactory

AddRequestParameterGatewayFilterFactory

AddResponseHeaderGatewayFilterFactory

DedupeResponseHeaderGatewayFilter

CircuitBreakerGatewayFilter

以状态码触发断路器

FallbackHeadersGatewayFilter

MapRequestHeaderGatewayFilter

PrefixPathGatewayFilter

前言

基于3.0.2版本的英文文档翻译,加上个人理解进行总结,如若有误,欢迎指正。

持续更新中,觉得有用的点个赞吧....

Gateway是什么

Gateway是一个构建于Spring Boot 2.x, Spring 5(Spring WebFlux), and Project Reactor的Spring生态系统之上的网关,旨在提共一个简单有效的方式路由接口,并提供跨领域的关注点,比如安全,监控,恢复能力。

能够使用网关去进行鉴权,日志记录等。

特征

  1. 基于springframework5、projectreactor和springboot2.0构建
  2. 能够匹配任何请求属性上的路由。
  3. 特定于路由的断言(Predicates )和过滤器(filters )
  4. 集成熔断
  5. 集成Spring Cloud DiscoveryClient
  6. 易于编写断言(Predicates )和过滤器(filters )
  7. 请求速率限制
  8. 路径重写

1.如何包含Spring Cloud Gateway

在pom文件中引入如下依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

Spring Cloud Gateway需要SpringBoot和SpringWebFlux提供的Netty作为运行时的容器。它不能在传统的Servlet容器中工作,也不能在构建为war。

2.关键词

Route:网关的基本构建模块,由一个id,一个目标url,一个断言器(Predicates )集合和过滤器(filters)集合组成,如果所有的断言器都是true,则匹配路由。

Predicate:   Java8的函数接口。输入类型是 Spring Framework ServerWebExchange.允许您匹配来自HTTP请求的任何内容,例如请求头或参数

Filter:被特定工厂构建的GatewayFilter实例。在这里,您可以在发送请求之前或之后修改请求和响应。

3.工作原理

原理图

原理

如果客户端向网关发起一个请求,网关处理器正确映射请求到对应的路由,就会把请求发送给网关web拦截器,这个拦截器会使用这个请求对应的过滤器链去执行这个请求。

过滤器被虚线分割的原因是,过滤器可以在代理请求发送之前和之后运行逻辑。执行所有“预”过滤器逻辑。然后发出代理请求。在发出代理请求之后,运行“post”过滤器逻辑。

注意

       spring.cloud.gateway.routes[0].uri=http://localhost     端口默认为80

       spring.cloud.gateway.routes[0].uri=https://localhost  端口默认为443

如果在没有端口的路由中定义的uri分别为HTTP和HTTPS uri获取默认端口值80和443。

4.在配置文件中配置Predicate和Gateway Filter的两种方式

简写

规则:配置由筛选器名称、等号(=)和用逗号(,)分隔的参数值识别。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue
        ## - Header=Connection,keep-alive

解释:当请求中的cookie包含名称为mycookie=mycookievalue的时候,匹配路由https://example.org

        其中Cookie是断言工厂的一种,其他可填写的断言可通过RoutePredicateFactory方式查找可填写的key,例如关于请求头的HeaderRoutePredicateFactory,就可以写为Header=Connection,keep-alive。

 

完全展开

键值对书写,一般带有name和args两个key.args是用于配置Predicate或Gateway Filter的键值对映射。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

5.Route Predicate Factories

匹配路由的断言工程,可根据各种条件进行路由的匹配。

AfterRoutePredicateFactory

作用:接收一个java ZonedDateTime类(格式为:2021-04-19T16:43:52.634+08:00[Asia/Shanghai])的时间参数。代表,在这个时间之后的请求才能正确匹配路由。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2021-04-19T17:42:47.789-07:00[Asia/Shanghai]

解释:在2021年4月19号17点42分后的请求才能正确路由到https://example.org

BeforeRoutePredicateFactory

作用:接收一个java ZonedDateTime类(格式为:2021-04-19T16:43:52.634+08:00[Asia/Shanghai])的时间参数。代表在这个时间之前的请求才能正确匹配路由。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Before=2021-04-19T17:42:47.789-07:00[Asia/Shanghai]

解释:在2021年4月19号17点42分之前的请求才能正确路由到https://example.org

BetweenRoutePredicateFactory

作用:接收两个java ZonedDateTime类(格式为:2021-04-19T16:43:52.634+08:00[Asia/Shanghai])的时间参数。代表在第一时间之后,第二个时间之前的请求能被正确路由。

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2021-04-19T00:00:00.000-00:00[America/Denver], 2021-04-20T00:00:00.000-00:00[America/Denver]

解释:在2021-4-19号到2021-4-20号间的请求能被正确路由到https://example.org

CookieRoutePredicateFactory

作用:接收两个参数,分别为name和regexp (java的正则表达式),cookie中携带参数(name)满足正则表达式(regexp ),则被路由

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

解释:当请求的cookie携带key为chocolate的,值匹配ch.p的表达式(即当chocolate=ch.p),则被路由到https://example.org

HeaderRoutePredicateFactory

作用:接收两个参数,分别为name和regexp (java的正则表达式),cookie中携带参数(name)满足正则表达式(regexp ),则被路由

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

解释:当请求头携带key为X-Request-Id的,值包含数字的情况下,则被路由到https://example.org

HostRoutePredicateFactory

作用:接收一个主机名称表达式集合的参数,该路径表达式支持ant-style风格。也支持模板变量(例如:{sub}.myhost.org)

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

解释:当请求头中有Host参数,且值为www.somehost.org 或者deta.somehost.org或者www.anotherhost.org时,能正确路由https://example.org

主机地址支持接收模板变量(例1.{sub}.somehost.org,当请求地址主机为www.somehost.org时,sub=www,以somehost.org结尾的主机地址都能被路由;

例子2:{sub},当请求地址为www.somehost.org,sub=www.somehost.org,代表来自任何主机的请求都能被路由。

Predicate会提取uri模板变量作为map集合,并放置在ServerWebExchange.getAttributes()中,key为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE,这些变量值能在GatewayFilter factories中使用。

MethodRoutePredicateFactory

作用:接收一个或多个http请求方法参数,如果请求方法匹配,则被路由。

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

解释:当http请求为get或post请求时,能正确路由https://example.org

PathRoutePredicateFactory

作用:接收两个参数,路径表达式(Spring PathMatcher patterns)集合和一个名为matchTrailingSlash(默认为true)的参数,如果请求路径能够匹配,则被路由

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

解释:当请求路径为/red/1 or /red/1/ or /red/blue or /blue/green时,能正确路由https://example.org

如果matchTrailingSlash为false,则 /red/1/不能被路由。

segment为predicate提取的模板变量,可使用工具类轻松获取。

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);

String segment = uriVariables.get("segment");

 

QueryRoutePredicateFactory

作用:提供两个参数:必选的param和可选的regexp。如果请求保护一个

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=color

解释:如果请求方法携带一个为color的参数,则路由匹配。例如:http://localhost:8080/getColor?color=green

- Query=color,gree. 如果请求方法携带一个为color的参数,且值为gree开头的,则路由匹配。例如:http://localhost:8080/getColor?color=green,http://localhost:8080/getColor?color=greet

ReadBodyPredicateFactory

备注:这个类为BETA,在未来版本中可能会被改动。

RemoteAddrRoutePredicateFactory

作用:接收一个至少为1个长度的(IPv4或IPv6地址字符串)的远程地址资源集合,例如192.168.0.1/16,192.168.0.1是地址,16是子网前缀范围地址。

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

解释:如果一个请求的远程地址为192.168.1.10,则路由匹配。

备注:默认情况下,RemoteAddrRoutePredicateFactory使用传入请求的的远程地址。如果gateway位于代理层之后,那么可能与实际的客户端ip地址不一致。可以通过设置自定义RemoteAddressResolver,可以自定义解析客户端ip获取方式。

Spring Cloud Gateway提供了一个基于X-Forwarded-For头的非默认远程地址解析器XForwardedRemoteAddressResolver。

XForwardedRemoteAddressResolver提供两个静态方法,采用不同的安全策略

trustAll:返回一个RemoteAddressResolver,它总是取X-Forwarded-For头中的第一个IP地址。它是易受欺骗攻击。因为恶意的客户端能够设置X-Forwarded-For的初始值。程序解析时,就会接受该值。

maxTrustedIndex:采用索引,而且该索引与Spring Cloud Gateway前面受信任的访问点有关。如果反问仅能通过HAProxy代理,那么maxTrustedIndex应该设置为1,如果有两个需要设置为2。

例如:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

maxTrustedIndex值将产生以下远程地址:

maxTrustedIndexresult

[Integer.MIN_VALUE,0]

(无效, 初始化期间抛出IllegalArgumentException )

1

0.0.0.3

2

0.0.0.2

3

0.0.0.1

[4, Integer.MAX_VALUE]

0.0.0.1

关于X-Forwarded-For的介绍

可以通过以下方式配置:

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
                .maxTrustedIndex(1);
        return builder.routes()
                .route("direct-route",r->r.remoteAddr("10.1.1.1","10.10.1.1/24").uri("https://downstream1"))
                .route("proxy-route",r->r.remoteAddr(resolver,"10.10.1.1","10.10.1.1/24").uri("https://downstream2"))
                .build();
    }
}

WeightRoutePredicateFactory

作用:权重路由断言接收两个参数,group和weight(int类型),每个组(group)根据权重进行计算。

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

解释:当客户端发起请求,80%被路由到https://weighthigh.org,20%被路由https://weightlow.org,可以进行负载均衡。

6.GatewayFilter Factories

路由过滤器运行以特定的方式修改传入的http请求或者传出的http响应,并往下游http传递修改后的信息。官方单元测试地址

过滤器命名方式都是xxxGatewayFilter.配置文件可填写的过滤器名称也都是GatewayFilter之前的名称。

AddRequestHeaderGatewayFilterFactory

作用:接收两个参数name,value。在修改传入的http请求,并往下游请求头添加信息。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://localhost:8086
        predicates:
            - Path=/comsuer-8086/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-Red,eee

解释:当访问http://localhost:8087/comsuer-8086/nacos/comsuer?user=zhangsan,时,路径匹配到后,会往请求头中添加X-Request-Red=eee,并路由到http://localhost:8087//nacos/comsuer?user=zhangsan,通过断点可以获取到请求头中X-Request-Red的信息为eee.

AddRequestHeader能够使用匹配path或host的uri变量

例如:

当传入请求http://localhost:8080/red/test时,segment=test,请求头中添加X-Request-Red=Blue-test,并传给下游请求获取。

{segment}相当于一个占位符,如果请求为http://localhost:8080/red/test/haha,则无法路由到https://example.org

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}

AddRequestParameterGatewayFilterFactory

作用:接收两个变量,name和value。给所有匹配路由规则的请求添加请求参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
            - AddRequestParameter=color, blue

解释:客户端像网关发起请求,会往匹配的路由https://example.org添加请求参数https://example.org?color=blue

支持uri变量,例如:

http://localhost:8080/red/test请求网关,{segment}=test,请求参数添加foo=bar-test,被路由到https://example.org后变成https://example.orgfoo=bar-test

 
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestParameter=foo, bar-{segment}

AddResponseHeaderGatewayFilterFactory

作用:接收两个参数name,value。在传出的http响应时,并往响应头添加信息。

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Bl

解释:当http请求返回时,响应头中会添加X-Response-Red=Bl

DedupeResponseHeaderGatewayFilter

作用:接收两个参数name(必填),strategy(可选)。name是一个以空格为分割符的集合。消除响应头中重复的数据。

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
         - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

解释:当网关跨域和下游请求都添加了Access-Control-Allow-Credentials和Access-Control-Allow-Origin,将会删除他们的重复值。

CircuitBreakerGatewayFilter

作用:使用Spring Cloud CircuitBreaker 的api将网关路由包装到熔断器中。Spring Cloud CircuitBreaker提供了多个库能够被网关使用。比如 Resilience4J的开箱即用。

想要启用Spring Cloud CircuitBreaker 过滤器的功能,需要引入spring-cloud-starter-circuitbreaker-reactor-resilience4j包,并根据如下配置:

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

解释:如何配置myCircuitBreaker,可以看Resilience4J Documentation

这个CircuitBreaker过滤器还可添加可选的参数fallbackUri。仅仅支持forward:约束的URIs 。如果失败回调被调用,将会转发到匹配这个uri的controller

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
        - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

也可以写成如下配置

Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

 当请求被熔断,失败回调时,会被转发到网关内部的控制器/inCaseofFailureUseThis。还可以使用重新路由请求到外部的控制器或拦截器的方式进行失败回调。

例如:

spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

以状态码触发断路器

在某些情况下,希望以路由返回的状态码来进行触发熔断。断路器配置状态码集合,如果返回的状态码保护在集合中,将触发断路器。状态码可以设置数值或字符串

例如:

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
            statusCodes:
              - 500
              - "NOT_FOUND"

使用bean方式配置

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

FallbackHeadersGatewayFilter

作用:当请求通过fallbackUri转发到外部应用时,FallbackHeaders允许添加Spring Cloud CircuitBreaker熔断器的异常信息到请求头中,

spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback
        filters:
        - name: FallbackHeaders
          args:
            executionExceptionTypeHeaderName: Test-Header

解释:当//ingredients/**的请求触发了熔断,回调了fallbackUri,将请求转发到/fallback,即匹配上ingredients-fallback路由,然后触发FallbackHeaders将异常信息Test-Header添加到请求头中,传给http://localhost:9994/fallback请求。

可以通过重写覆盖请求头的名称,以下展示了默认值:

  • executionExceptionTypeHeaderName ("Execution-Exception-Type")

  • executionExceptionMessageHeaderName ("Execution-Exception-Message")

  • rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")

  • rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")

更多关于熔断器和网关的信息可查看Spring Cloud CircuitBreaker Factory section.

MapRequestHeaderGatewayFilter

作用:MapRequestHeader提供两个参数fromHeader,toHeader。会将传入的请求中对应请求头(fromHeader参数对应得请求头名称)得信息,赋值给toHeader请求头,以供下游使用。

spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        - MapRequestHeader=Blue, X-Request-Red

解释:如果传入的http请求头携带Blue名称的值,MapRequestHeader将会根据Blue对应得值更新X-Request-Red,并添加到请求头:X-Request-Red:<values>。如果没有Blue请求头,MapRequestHeader将不会被触发。

PrefixPathGatewayFilter

作用:提供一个prefix的参数。给传入的请求添加前缀。

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

解释:所有匹配的请求将添加/mypath路径,例如/red请求,将变成/mypath/red.

GatewayFilter其余过滤器待续。。。。。。。

其余文档链接

2021年Spring Cloud Gateway中文文档详细解析(7-·19章)(3.0.2版)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿孟呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值