SpringCloud Gateway使用及原理分析大全——断言及过滤器(上篇)

文章目录

  • 写在前面
  • 一、熟悉Gateway基本概念与原理
    • 1、三大概念
    • 2、工作流程
  • 二、基本使用
    • 路由断言的两种写法
  • 三、路由断言工厂
    • 1、After路由断言工厂
    • 2、Before路由断言工厂
    • 3、Between路由断言工厂
    • 4、Cookie路由断言工厂
    • 5、Header路由断言工厂
    • 6、Host路由断言工厂
    • 7、Method路由断言工厂
    • 8、Path路由断言工厂
    • 9、Query路由断言工厂
    • 10、RemoteAddr 路由断言工厂
      • 修改远程地址的解析方式
    • 11、Weight 路由断言工厂
    • 12、XForwarded Remote Addr路由断言工厂
  • 四、GatewayFilter-网关过滤工厂
    • 1、AddRequestHeader 网关过滤工厂
    • 2、AddRequestParameter 网关过滤工厂
    • 3、AddResponseHeader 网关过滤工厂
    • 4、DedupeResponseHeader 网关过滤工厂
    • 5、SpringCloud断路器网关过滤工厂
      • 根据状态代码使断路器跳闸
    • 6、FallbackHeaders 网关过滤工厂
    • 7、MapRequestHeader 网关过滤工厂
    • 8、PrefixPath 网关过滤工厂
    • 9、PreserveHostHeader 网关过滤工厂
    • 10、RequestRateLimiter 网关过滤工厂
      • redis限流
    • 11、RedirectTo 网关过滤工厂
    • 12、RemoveRequestHeader 网关过滤工厂
    • 13、RemoveResponseHeader 网关过滤工厂
    • 14、RemoveRequestParameter网关过滤工厂
    • 15、RequestHeaderSize 网关过滤 工厂
    • 16、RewritePath 网关过滤工厂
    • 17、RewriteLocationResponseHeader 网关过滤器
    • 18、RewriteResponseHeader 网关过滤工厂
    • 19、SaveSession 网关过滤工厂
    • 20、SecureHeaders 网关过滤工厂
    • 21、SetPath 网关过滤工厂
    • 22、SetRequestHeader 网关过滤工厂
    • 23、SetResponseHeader 网关过滤工厂
    • 24、SetStatus 网关过滤工厂
    • 25、StripPrefix 网关过滤工厂
    • 26、Retry 网关过滤工厂
    • 27、RequestSize 网关过滤器
    • 28、SetRequestHostHeader 网关过滤器
    • 29、ModifyRequestBody 网关过滤器
    • 30、ModifyResponseBody 网关过滤器
    • 31、Token Relay网关过滤器
    • 32、CacheRequestBody 网关过滤器
    • 33、 JSONToGRPC网关过滤器
    • 34、Default过滤器
  • 参考资料

SpringCloud Gateway使用及原理分析大全——断言及过滤器(上篇)

SpringCloud Gateway使用及原理分析大全(下篇)

写在前面

Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是用的Zuul作为网关。
但是在2.x版本中,zuul的升级维护变得困难,SpringCloud最后自己研发了一个网关替代Zuul,那就是SpringCloud Gateway,使用gateway替代了zuul。

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring5、SpringBoot2.0和Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等。

Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行环境。它不能在传统的Servlet容器中工作,也不能作为WAR来构建。

SpringCloud Gateway使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
SpringCloud Gateway使用及原理分析大全——断言及过滤器(上篇)_第1张图片

一、熟悉Gateway基本概念与原理

1、三大概念

路由(Route):路由是构建网关的基本模块,它由ID、目标URI、一系列的断言和过滤器组成,如果断言为true则匹配该路由。

断言(Predicate):参考Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。

过滤(Filter):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

总的来说,web请求,通过一些匹配条件,定位到真正的服务节点,并在这个转发过程的前后,进行一些精细化控制。
prodicate就是我们的匹配条件;而filter可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了。

2、工作流程

客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定一个请求与一个路由匹配,它将被发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“预”过滤器逻辑。然后进行代理请求。发出代理请求后,将运行“post”过滤器逻辑。

注:在没有端口的路由中定义的URIs分别为HTTP和HTTPS URIs获得默认端口值80和443。

总结Gateway工作流程:
(1)客户端向SpringCloudGateway发出请求。然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway Web Handler。
(2)Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
(3)过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或之后(post)执行业务逻辑。
(4)Filter在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等。
(5)在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

SpringCloud Gateway使用及原理分析大全——断言及过滤器(上篇)_第2张图片

二、基本使用

1、pom配置


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-gatewayartifactId>
dependency>

注意:Gateway并不需要以下配置:

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-actuatorartifactId>
dependency>

2、配置yml文件

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由


        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
            #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式

eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka.com:7001/eureka

路由断言的两种写法

1、简短断言

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

2、完整断言

通常,会有一个name键和一个args键。args键是键值对的映射,用于配置断言或过滤器。

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

三、路由断言工厂

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。

Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些Predicate都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行结合。

Spring Cloud Gateway创建Route对象时,使用RoutePredicateFactory创建Predicate对象,Predicate对象可以赋值给Route。Spring Cloud Gateway包含许多内置的Route Predicate Factiries。

所有这些断言(Predicate)都匹配HTTP请求的不同属性。多种断言工厂可以结合,并通过逻辑and。

1、After路由断言工厂

After 路由断言工厂接受一个参数datetime(java的ZonedDateTime)。该断言匹配在指定日期时间之后发生的请求。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        # 东八区时间2022-09-25 15:00:00.000之后所有的请求,都会匹配到
        - After=2022-09-25T15:00:00.000+08:00[Asia/Shanghai]

2、Before路由断言工厂

Before 路由断言工厂接受一个参数datetime(java的ZonedDateTime)。该断言匹配在指定日期时间之前发生的请求。

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        # 东八区时间2022-09-25 15:00:00.000之前所有的请求,都会匹配到
        - Before=2022-09-25T15:00:00.000+08:00[Asia/Shanghai]

3、Between路由断言工厂

Between route断言工厂接受两个参数,datetime1和datetime2,它们是java ZonedDateTime对象。该断言匹配发生在datetime1之后和datetime2之前的请求。datetime2参数必须在datetime1之后。

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        # 东八区时间2022-09-25 15:00:00.000 到2022-09-26 15:00:00.000 之间的请求都会被匹配到
        - Between=2022-09-25T15:00:00.000+08:00[Asia/Shanghai], 2022-09-26T15:00:00.000+08:00[Asia/Shanghai]

4、Cookie路由断言工厂

cookie路由断言工厂接受两个参数,Cookie名称和一个regexp(Java正则表达式)。该谓词匹配具有给定名称并且其值匹配正则表达式的cookies。

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        # cookie的key为mycookie,value为mycookievalue时会匹配到
        - Cookie=mycookie,mycookievalue

5、Header路由断言工厂

Header route断言工厂接受两个参数,Header和一个regexp(Java正则表达式)。该断言与具有给定名称的请求头匹配,该请求头的值与正则表达式匹配。

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        # 请求头X-Request-Id的值为一个或多个数字,会被匹配到
        - Header=X-Request-Id, \d+

6、Host路由断言工厂

Host路由断言工厂接受一个参数:主机名表达式列表。用’.'作为分隔符。这个断言匹配与表达式匹配的主机头。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        # somehost.org结尾、anotherhost.org结尾的Host都能匹配到
        # 也支持URI模板变量(如{sub}.myhost.org)
        - Host=**.somehost.org,**.anotherhost.org

该断言提取URI模板变量(如{sub},在前面的示例中定义)作为名称和值的映射,并将其放入ServerWebExchange.getAttributes()中,并在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定义一个键。这些值随后可供GatewayFilter工厂使用。

7、Method路由断言工厂

方法路由断言工厂接受一个方法参数,它是一个或多个参数——要匹配的HTTP方法。

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        # GET、POST请求会被匹配到
        - Method=GET,POST

8、Path路由断言工厂

路径路由断言工厂接受两个参数:一个Spring PathMatcher 表达式列表和一个名为matchTrailingSlash的可选标志(默认为true)。

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        # /red/1或/red/1/或/red/blue或/blue/green 都能匹配到
        - Path=/red/{segment},/blue/{segment}

如果matchTrailingSlash 设置了false,那么 /red/1/ 就匹配不到了。

该断言提取URI模板变量(如{segment},在前面的示例中定义)作为名称和值的映射,并将其放入ServerWebExchange.getAttributes()中,并在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定义一个键。这些值随后可供GatewayFilter工厂使用。

// 可以用以下方式获取变量参数
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");

9、Query路由断言工厂

查询路由谓词工厂有两个参数:一个必需的参数和一个可选的regexp(Java正则表达式)。

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        # 如果请求包含green查询参数,会被匹配到
        - Query=green
        # red、green、greet都能匹配到,支持正则
		# - Query=red, gree.

10、RemoteAddr 路由断言工厂

RemoteAddr路由断言工厂接受一个源列表(最小大小为1),这些源是CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        # 192.168.1.10会被匹配到
        - RemoteAddr=192.168.1.1/24

修改远程地址的解析方式

默认情况下,RemoteAddr路由断言工厂使用来自传入请求的远程地址。如果Spring Cloud Gateway位于代理层之后,这可能与实际的客户端IP地址不匹配。

通过设置自定义RemoteAddressResolver,可以自定义解析远程地址的方式。Spring Cloud Gateway附带了一个非默认的远程地址解析器,它基于X-Forwarded-For Header,XForwardedRemoteAddressResolver。

XForwardedRemoteAddressResolver有两个静态构造函数方法,它们采用不同的安全性方法:

  • XForwardedRemoteAddressResolver::trustAll 返回一个RemoteAddressResolver,它总是采用在X-Forwarded-For标头中找到的第一个IP地址。这种方法容易受到欺骗,因为恶意客户端可以为X-Forwarded-For设置初始值,解析器会接受该初始值。
  • XForwardedRemoteAddressResolver::maxTrustedIndex采用一个与Spring Cloud Gateway前端运行的可信基础设施数量相关的索引。例如,如果Spring Cloud Gateway只能通过HAProxy访问,则应使用值1。如果在访问Spring Cloud Gateway之前需要可信基础设施的两跳,那么应该使用值2。

例如以下的请求头:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

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

maxTrustedIndex result
[Integer.MIN_VALUE,0] (invalid, IllegalArgumentException during initialization)
1 0.0.0.3
2 0.0.0.2
3 0.0.0.1
[4, Integer.MAX_VALUE] 0.0.0.1
// 用java实现
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)

11、Weight 路由断言工厂

权重路由断言工厂接受两个参数:group和Weight(int类型)。权重按组计算。

spring:
  cloud:
    gateway:
      routes:
      # 这条路线将大约80%的流量转发到weighthigh.org,大约20%的流量转发到weighlow.org
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

12、XForwarded Remote Addr路由断言工厂

XForwarded Remote Addr route断言工厂接受一个源列表(最小大小为1),这些源是CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。这个路由断言允许基于X-Forwarded-For HTTP头过滤请求。

这可以用于反向代理,如负载平衡器或web应用程序防火墙,其中只有当请求来自这些反向代理使用的IP地址的可信列表时,才应该允许该请求。

spring:
  cloud:
    gateway:
      routes:
      - id: xforwarded_remoteaddr_route
        uri: https://example.org
        predicates:
        # X-Forwarded-For报问头包含192.168.1.10等,则匹配
        - XForwardedRemoteAddr=192.168.1.1/24

四、GatewayFilter-网关过滤工厂

路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用范围是特定的路由。Spring Cloud Gateway包括许多内置的GatewayFilter工厂。

1、AddRequestHeader 网关过滤工厂

AddRequestHeader 网关过滤工厂接受一个name和value参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        # 将X-Request-red:blue 请求头加入到所有下游的请求中
        - AddRequestHeader=X-Request-red, blue
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        # 也可以使用uri参数
        - AddRequestHeader=X-Request-Red, Blue-{segment}

2、AddRequestParameter 网关过滤工厂

AddRequestParameter 网关过滤工厂接受一个name和value参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        # 为所有匹配的请求 向下游请求的查询参数添加red=blue
        - AddRequestParameter=red, blue
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        # 也可以使用url中的参数
        - AddRequestParameter=foo, bar-{segment}

3、AddResponseHeader 网关过滤工厂

AddResponseHeader GatewayFilter工厂接受一个name和value参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        # 这将X-Response-Red:Blue头添加到所有匹配请求的下游响应的头中。
        - AddResponseHeader=X-Response-Red, Blue
spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        # 也可以使用url中的参数
        - AddResponseHeader=foo, bar-{segment}

4、DedupeResponseHeader 网关过滤工厂

DedupeResponseHeader GatewayFilter 工厂接受一个名称参数和一个可选的策略参数。name可以包含以空格分隔的标头名称列表。

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        # 消除网关CORS逻辑和下游逻辑的Access-Control-Allow-Credentials和Access-Control-Allow-Origin响应报头的重复值
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

DedupeResponseHeader筛选器还接受一个可选的策略参数。接受的值为RETAIN_FIRST(默认值)、RETAIN_LAST和RETAIN_UNIQUE。
RETAIN_FIRST 默认值,保留第一个
RETANIN_LAST 保留最后一个
RETAIN_UNIQUE 保留唯一的,出现重复的属性值,会保留一个。例如有两个my:bbb的属性,最后会留一个。

5、SpringCloud断路器网关过滤工厂

Spring Cloud 断路器网关工厂使用Spring Cloud 断路器 API将网关路由包装在断路器中。Spring Cloud 断路器支持多个可以与Spring Cloud 网关一起使用的库。

要启用Spring Cloud 断路器过滤器,需要引入spring-cloud-starter-circuitbreaker-reactor-resilience4j依赖。
断路器官方文档:https://cloud.spring.io/spring-cloud-circuitbreaker/reference/html/spring-cloud-circuitbreaker.html

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

Spring Cloud 断路器过滤器也可以接受一个可选的fallbackUri参数。目前,仅支持正向:计划的URI。如果调用回退,请求将被转发到URI匹配的控制器。

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
// 使用java配置
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
// 当调用断路器回退时,此示例转发到/inCaseofFailureUseThis。请注意,该示例还演示了(可选的)Spring Cloud LoadBalancer负载平衡(由目标URI上的lb前缀定义)。
    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();
}

主要场景是使用fallbackUri在网关应用程序中定义内部控制器或处理程序。

spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
		# 也可以将请求重新路由到外部应用程序中的控制器或处理程序,以下实例中网关应用程序中没有回退端点或处理程序。但是,在另一个应用程序中有一个,注册在localhost:9994下。	
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

在请求被转发到回退的情况下,Spring Cloud 断路器网关过滤器还提供了导致它的Throwable。它作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR属性添加到ServerWebExchange中,在网关应用程序中处理回退时可以使用。

对于外部控制器/处理器场景,可以添加带有异常细节的头。可以参考FallbackHeaders 网关过滤工厂

根据状态代码使断路器跳闸

在某些情况下,可能希望根据断路器所环绕的路径返回的状态代码来触发断路器。断路器配置对象获取状态代码列表,如果返回,将导致断路器跳闸。当设置想要使断路器跳闸的状态代码时,可以使用带有状态代码值的整数,也可以使用HttpStatus枚举的字符串表示。

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"
// 使用java配置
@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();
}

6、FallbackHeaders 网关过滤工厂

FallbackHeaders 工厂允许在转发给外部应用程序中的fallbackUri的请求的标头中添加Spring Cloud 断路器执行异常详细信息。

spring:
  cloud:
    gateway:
      routes:
      # 在运行断路器时发生执行异常后,请求被转发到在localhost:9994上运行的应用程序中的回退端点或处理程序。FallbackHeaders过滤器会将具有异常类型、消息和(如果可用)根本原因异常类型和消息的标头添加到该请求中。
      - 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

可以通过设置以下参数的值来覆盖配置中的标题名称(显示为默认值):

  • executionExceptionTypeHeaderName (“Execution-Exception-Type”)
  • executionExceptionMessageHeaderName (“Execution-Exception-Message”)
  • rootCauseExceptionTypeHeaderName (“Root-Cause-Exception-Type”)
  • rootCauseExceptionMessageHeaderName (“Root-Cause-Exception-Message”)

FallbackHeaders 网关过滤工厂用法和SpringCloud断路器网关过滤工厂 类似。

7、MapRequestHeader 网关过滤工厂

MapRequestHeader GatewayFilter工厂采用fromHeader和toHeader参数。它创建一个新的命名头(toHeader),并且从传入的http请求中的现有命名头(fromHeader)中提取值。如果输入头不存在,过滤器没有影响。如果新的命名头已经存在,它的值将增加新值。

spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        # 这将X-Request-Red: 请求头添加到下游请求中,其中包含来自传入HTTP请求的Blue请求头的值。
        - MapRequestHeader=Blue, X-Request-Red

8、PrefixPath 网关过滤工厂

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        # 素有匹配的请求都会添加/mypath作为路径的前缀。比如/hello请求将被发送到/mypath/hello
        - PrefixPath=/mypath

9、PreserveHostHeader 网关过滤工厂

为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host Header。如果不设置,那么名为 Host 的Header将由Http Client控制。

spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: https://example.org
        filters:
        - PreserveHostHeader

10、RequestRateLimiter 网关过滤工厂

RequestRateLimiter GatewayFilter工厂使用RateLimiter实现来确定是否允许当前请求继续进行。如果不是,则默认返回HTTP 429 - Too Many Requests状态。

该过滤器采用可选的keyResolver参数和速率限制器特定的参数。

keyResolver是一个实现KeyResolver接口的bean。在配置中,使用SpEL通过名称引用bean。#{@myKeyResolver}是一个引用名为myKeyResolver的bean的SpEL表达式。

// KeyResolver 接口
public interface KeyResolver {
    Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver接口让可插拔策略派生出限制请求的密钥。在未来的版本中,将会有一些KeyResolver实现。

KeyResolver的默认实现是PrincipalNameKeyResolver,它从ServerWebExchange检索主体并调用Principal.getName()。

默认情况下,如果KeyResolver没有找到密钥,请求将被拒绝。可以通过设置spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true or false) 、spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code

RequestRateLimiter不能用“快捷方式”符号进行配置。下面的例子是无效的:

# 无效的快捷配置
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

redis限流

Redis的实现基于Stripe所做的。它需要引入spring-boot-starter-data-redis-reactive依赖。使用的算法是令牌桶算法。

redis-rate-limiter.replenishRate属性是允许用户每秒处理多少请求,而不丢弃任何请求,多余的请求排队处理。这是令牌桶的填充速率。
redis-rate-limiter.burstCapacity属性是允许用户在一秒钟内进行的最大请求数。这是令牌桶可以容纳的令牌数。将该值设置为零会阻止所有请求。
redis-rate-limiter.requestedTokens属性是一个请求花费多少令牌。这是每个请求从桶中获取的令牌数,默认为1。

通过在replenishRate和burstCapacity中设置相同的值来实现稳定的速率。通过将burstCapacity设置为高于replenishRate,可以允许临时突发。在这种情况下,需要允许速率限制器在突发之间有一段时间(根据replenishRate),因为两个连续的突发将导致丢弃请求(HTTP 429 - Too Many Requests)。

低于1个请求/秒的速率限制是通过将replenishRate设置为所需的请求数,将requestedTokens设置为以秒为单位的时间跨度,将burstCapacity设置为replenishRate和requestedTokens的乘积来实现的,例如,设置replenishRate=1、requestedTokens=60和burstCapacity=60将导致1个请求/分钟的限制。

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
          # 每秒最多处理10个请求,每秒最大20个请求,请求一次花费1个令牌
          # 这定义了每个用户10的请求速率限制。允许20个突发,但是在下一秒,只有10个请求可用。
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20
            redis-rate-limiter.requestedTokens: 1
// 使用java配置一个KeyResolver KeyResolver是一个简单的工具,它获取用户请求参数(注意,不建议在生产中使用)。
@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        # 还可以将速率限制器定义为实现RateLimiter 接口的bean。
        # 在配置中,可以使用SpEL通过名称引用bean。#{@myRateLimiter}是一个引用名为myRateLimiter的bean的SpEL表达式。
        # 下面的清单定义了一个速率限制器,它使用前面清单中定义的KeyResolver
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@myRateLimiter}"
            key-resolver: "#{@userKeyResolver}"

11、RedirectTo 网关过滤工厂

RedirectTo GatewayFilter工厂有两个参数,status和url。status参数应该是300系列重定向HTTP代码,比如301。url参数应该是有效的URL。这是位置头的值。对于相对重定向,应该使用uri: no://op作为路由定义的uri。

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        # 这将发送带有Location:https://acme.org头的状态302来执行重定向。
        - RedirectTo=302, https://acme.org

12、RemoveRequestHeader 网关过滤工厂

RemoveRequestHeader gateway filter工厂接受一个名称参数。这是要删除的请求头的名称。

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        # 网下游发请求时,删除X-Request-Foo 请求头
        - RemoveRequestHeader=X-Request-Foo

13、RemoveResponseHeader 网关过滤工厂

RemoveResponseHeader gateway filter工厂接受一个名称参数。这是要删除的请求头的名称。

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        # 在响应返回前 删除X-Response-Foo请求头。
        - RemoveResponseHeader=X-Response-Foo

注意:要删除任何类型的敏感请求头,应该为想要删除的任何路由配置此过滤器。
此外,您可以使用spring.cloud.gateway.default-filters配置此过滤器一次,并将其应用于所有路由。

14、RemoveRequestParameter网关过滤工厂

RemoveRequestParameter gateway filter工厂接受一个名称参数。这是要删除的查询参数的名称。

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        # 往下游系统发送的请求,都删掉red参数
        - RemoveRequestParameter=red

15、RequestHeaderSize 网关过滤 工厂

RequestHeaderSize GatewayFilter工厂采用maxSize和errorHeaderName参数。maxSize参数是请求标头中允许的最大数据大小(包括键和值)。errorHeaderName参数设置包含错误消息的响应头的名称,默认情况下为“error message”。

spring:
  cloud:
    gateway:
      routes:
      - id: requestheadersize_route
        uri: https://example.org
        filters:
        # 如果任何请求报头的大小大于1000字节,这将发送状态431。
        - RequestHeaderSize=1000B

16、RewritePath 网关过滤工厂

RewritePath GatewayFilter工厂接受一个路径regexp参数和一个替换参数。这使用Java正则表达式以灵活的方式重写请求路径。

spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        # 对于/red/blue请求路径,这将在发出下游请求之前将路径设置为/blue。请注意,根据YAML规范,$应该替换为$\。
        - RewritePath=/red/?(?<segment>.*), /$\{segment}

17、RewriteLocationResponseHeader 网关过滤器

RewriteLocationResponseHeader gateway filter工厂修改位置响应头的值,通常是为了消除后端特定的细节。它采用stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数。

spring:
  cloud:
    gateway:
      routes:
      - id: rewritelocationresponseheader_route
        uri: http://example.org
        filters:
        # 比如,一个post请求api.example.com/some/object/name,Location 的响应头object-service.prod.example.net/v2/some/object/id值会被重写为api.example.com/some/object/id
        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

stripVersionMode参数有以下可能值:NEVER_STRIP、AS_IN_REQUEST(默认值)和ALWAYS_STRIP。

  • NEVER_STRIP:不剥离版本,即使原始请求路径不包含版本。
  • AS_IN_REQUEST仅当原始请求路径不包含版本时,才剥离版本。
  • LWAYS_STRIP总是剥离版本,即使原始请求路径包含版本。

hostValue参数(如果提供)用于替换响应位置标头的host:port部分。如果没有提供,则使用主机请求头的值。
protocolsRegex参数必须是有效的Regex字符串,协议名称与之匹配。如果不匹配,过滤器什么也不做。默认为http|https|ftp|ftps。

18、RewriteResponseHeader 网关过滤工厂

RewriteResponseHeader gateway filter工厂接受name、正则表达式和replacement参数。它使用Java正则表达式以灵活的方式重写响应头值。

spring:
  cloud:
    gateway:
      routes:
      - id: rewriteresponseheader_route
        uri: https://example.org
        filters:
        # 一个头的值为 /42?user=ford&password=omg!what&flag=true,在发出下游请求后,将此头设置为 /42?user=ford&password=***&flag=true。注意使用 $\ 代表 $,这是 YAML 格式指定的。
        - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***

19、SaveSession 网关过滤工厂

在向下游转发调用之前,SaveSession GatewayFilter工厂强制执行WebSession::save操作。这在使用类似Spring Session的惰性数据存储时特别有用,需要确保在进行转发调用之前保存会话状态。

spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: https://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

如果将Spring安全性与Spring Session集成在一起,并希望确保安全性细节已经被转发到远程进程,这一点非常重要。

20、SecureHeaders 网关过滤工厂

SecureHeaders GatewayFilter工厂根据这篇博客文章中的建议向响应添加了许多请求头。

  • X-Xss-Protection:1 (mode=block)
  • Strict-Transport-Security (max-age=631138519)
  • X-Frame-Options (DENY)
  • X-Content-Type-Options (nosniff)
  • Referrer-Policy (no-referrer)
  • Content-Security-Policy (default-src ‘self’ https:; font-src ‘self’ https: data:; img-src ‘self’ https: data:; object-src ‘none’; script-src https:; style-src ‘self’ https: ‘unsafe-inline)’
  • X-Download-Options (noopen)
  • X-Permitted-Cross-Domain-Policies (none)

要更改默认值,请在spring.cloud.gateway.filter.secure-headers名称空间中设置适当的属性。以下是可用的属性:

  • xss-protection-header
  • strict-transport-security
  • x-frame-options
  • x-content-type-options
  • referrer-policy
  • content-security-policy
  • x-download-options
  • x-permitted-cross-domain-policies

若要禁用默认值,请使用逗号分隔值设置spring.cloud.gateway.filter.secure-headers.disable属性:

# 需要使用安全标头的小写全名来禁用它
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security

21、SetPath 网关过滤工厂

SetPath GatewayFilter工厂采用路径模板参数。它提供了一种简单的方法,通过允许路径的模板段来操作请求路径。这使用了Spring框架中的URI模板。允许多个匹配段。

spring:
  cloud:
    gateway:
      routes:
      # 对于/red/blue请求路径,这将在发出下游请求之前将路径设置为/blue。
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}

22、SetRequestHeader 网关过滤工厂

SetRequestHeader GatewayFilter工厂接受name和value参数。

spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        filters:
        # X-Request-Red:1234 下游请求头将会被替换为X-Request-Red:Blue
        - SetRequestHeader=X-Request-Red, Blue
spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        # 也可以使用path路径上的参数
        - SetRequestHeader=foo, bar-{segment}

23、SetResponseHeader 网关过滤工厂

SetResponseHeader GatewayFilter工厂接受name和value参数。

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        filters:
        # X-Request-Red:1234 下游响应头将会被替换为X-Request-Red:Blue
        - SetResponseHeader=X-Response-Red, Blue
spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        # 也可以使用path路径上的参数
        - SetResponseHeader=foo, bar-{segment}

24、SetStatus 网关过滤工厂

SetStatus GatewayFilter工厂接受单个参数Status。它必须是有效的Spring HttpStatus。它可以是整数值404或枚举的字符串表示:NOT_FOUND。

spring:
  cloud:
    gateway:
      routes:
      # 在这两种情况下,响应的HTTP状态都设置为401。
      - id: setstatusstring_route
        uri: https://example.org
        filters:
        - SetStatus=UNAUTHORIZED
      - id: setstatusint_route
        uri: https://example.org
        filters:
        - SetStatus=401
# 可以将SetStatus GatewayFilter配置为在响应的标头中返回代理请求的原始HTTP状态代码。如果使用以下属性进行配置,标头将被添加到响应中:
spring:
  cloud:
    gateway:
      set-status:
        original-status-header-name: original-http-status

25、StripPrefix 网关过滤工厂

StripPrefix GatewayFilter工厂接受一个参数parts。parts参数指示在将请求发送到下游之前,路径中要从请求中去除的部分的数量。

spring:
  cloud:
    gateway:
      routes:
      # 当通过网关向/name/blue/red发出请求时,向nameservice发出的请求看起来像nameservice/red。
      - id: nameRoot
        uri: https://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

26、Retry 网关过滤工厂

重试网关过滤器工厂支持以下参数:

  • retries:应该尝试的重试次数
  • statuses:应该重试的状态码,用org.springframework.http.HttpStatus表示。
  • methods:应该重试的HTTP方法,org.springframework.http.HttpMethod。
  • series:要重试的状态代码系列,用org.springframework.http.HttpStatus.Series表示。
  • exceptions:应该重试的引发异常的列表。
  • backoff:为重试配置的指数补偿。在firstBackoff * (factor ^ n)的补偿间隔之后执行重试,其中n是迭代。如果配置了maxBackoff,则应用的最大回退限制为maxBackoff。如果basedOnPreviousValue为true,则通过使用prevBackoff * factor来计算补偿。

如果启用了重试过滤器,则为其配置以下默认值:

  • retries:三次。
  • series:5xx状态码。
  • methods:Get方法
  • exceptions:IOException 和TimeoutException
  • backoff:未开启
spring:
  cloud:
    gateway:
      routes:
      # 配置重试网关过滤器
      - id: retry_test
        uri: http://localhost:8080/flakey
        predicates:
        - Host=*.retry.com
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY
            methods: GET,POST
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false
# 简写 对比
spring:
  cloud:
    gateway:
      routes:
      - id: retry_route
        uri: https://example.org
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: INTERNAL_SERVER_ERROR
            methods: GET
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false

      - id: retryshortcut_route
        uri: https://example.org
        filters:
        - Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false

27、RequestSize 网关过滤器

当请求大小大于允许的限制时,RequestSize GatewayFilter工厂可以限制请求到达下游服务。该筛选器采用maxSize参数。maxSize是一种数据大小类型,因此可以将值定义为一个数字,后跟一个可选的数据单元后缀,如“KB”或“MB”。字节的默认值为“B”。这是以字节定义的请求的允许大小限制。

spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

当请求因大小而被拒绝时,RequestSize GatewayFilter工厂将响应状态设置为413 Payload Too Large,并附加一个报头errorMessage。

errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB

如果没有在路由定义中作为过滤器参数提供,则默认请求大小被设置为5mb。

28、SetRequestHostHeader 网关过滤器

在某些情况下,主机标头可能需要被覆盖。在这种情况下,SetRequestHostHeader gateway filter工厂可以用指定的值替换现有的主机头。过滤器接受一个主机参数。

spring:
  cloud:
    gateway:
      routes:
      - id: set_request_host_header_route
        uri: http://localhost:8080/headers
        predicates:
        - Path=/headers
        filters:
        # SetRequestHostHeader gateway filter工厂将主机头的值替换为example.org。
        - name: SetRequestHostHeader
          args:
            host: example.org

29、ModifyRequestBody 网关过滤器

可以使用ModifyRequestBody过滤器在网关向下游发送请求正文之前对其进行修改。

这个过滤器只能通过使用Java DSL来配置。

// 修改请求正文
// 如果请求没有正文,RewriteFilter将被传递为null。应该返回Mono.empty()来分配请求中缺少的主体。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
                    (exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
        .build();
}

static class Hello {
    String message;

    public Hello() { }

    public Hello(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

30、ModifyResponseBody 网关过滤器

可以使用ModifyResponseBody过滤器在响应正文被发送回客户端之前对其进行修改。

这个过滤器只能通过使用Java DSL来配置。

// 修改响应正文
// 如果请求没有正文,RewriteFilter将被传递为null。应该返回Mono.empty()来分配请求中缺少的主体。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
                    (exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
        .build();
}

static class Hello {
    String message;

    public Hello() { }

    public Hello(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

31、Token Relay网关过滤器

在令牌中继中,OAuth2使用者充当客户端,并将传入的令牌转发给传出的资源请求。消费者可以是纯粹的客户机(像SSO应用程序)或资源服务器。

Spring Cloud Gateway可以将OAuth2访问令牌向下游转发给它所代理的服务。要将此功能添加到网关,您需要像这样添加TokenRelayGatewayFilterFactory:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("resource", r -> r.path("/resource")
                    .filters(f -> f.tokenRelay())
                    .uri("http://localhost:9000"))
            .build();
}

或者使用yml配置

spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

它还会(除了让用户登录并获取令牌之外)将身份验证令牌向下游传递给服务(在本例中为/resource)。
要为Spring Cloud Gateway实现这一点,需要添加以下依赖项:

org.springframework.boot:spring-boot-starter-oauth2-client

它是如何工作的?{githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter]从当前通过身份验证的用户中提取一个访问令牌,并将其放入下游请求的请求标头中。

32、CacheRequestBody 网关过滤器

有某些情况需要读正文。因为请求体流只能被读取一次,所以我们需要缓存请求体。
可以使用CacheRequestBody过滤器在请求正文发送到下游之前对其进行缓存,并从exchagne属性中获取正文。

// 进行缓存
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("cache_request_body_route", r -> r.path("/downstream/**")
            .filters(f -> f.prefixPath("/httpbin")
                .cacheRequestBody(String.class).uri(uri))
        .build();
}
# 进行缓存
spring:
  cloud:
    gateway:
      routes:
      - id: cache_request_body_route
        uri: lb://downstream
        predicates:
        - Path=/downstream/**
        filters:
        - name: CacheRequestBody
          args:
            bodyClass: java.lang.String

CacheRequestBody将提取请求体,并将其转换为Body类(如前面的示例中定义的java.lang.String)。然后用ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR中定义的键将其放入ServerWebExchange.getAttributes()中。

此过滤器仅适用于http请求(包括https)。

33、 JSONToGRPC网关过滤器

JSONToGRPCFilter GatewayFilter工厂将JSON有效负载转换为gRPC请求。

该过滤器采用以下参数:
protoDescriptor :原型描述符文件。

可以使用指定–descriptor_set_out标志的协议生成该文件:

protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb  \
src/main/resources/proto/hello.proto
  • protoFile :原型定义文件
  • service :将处理请求的服务的完全限定名。
  • method :服务中处理请求的方法名。

注意:不支持streaming 。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("json-grpc", r -> r.path("/json/hello").filters(f -> {
                String protoDescriptor = "file:src/main/proto/hello.pb";
                String protoFile = "file:src/main/proto/hello.proto";
                String service = "HelloService";
                String method = "hello";
                return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
            }).uri(uri))
spring:
  cloud:
    gateway:
      routes:
        - id: json-grpc
          uri: https://localhost:6565/testhello
          predicates:
            - Path=/json/**
          filters:
            - name: JsonToGrpc
              args:
                protoDescriptor: file:proto/hello.pb
                protoFile: file:proto/hello.proto
                service: com.example.grpcserver.hello.HelloService
                method: hello

当通过网关向/json/hello发出请求时,请求将使用hello.proto中提供的定义进行转换,发送到com.example.grpcserver.hello.HelloService/hello,,并将响应转换回json。

默认情况下,它将使用默认的TrustManagerFactory创建一个NettyChannel。但是,可以通过创建GrpcSslConfigurer类型的bean来定制这个信任管理器:

@Configuration
public class GRPCLocalConfiguration {
    @Bean
    public GRPCSSLContext sslContext() {
        TrustManager trustManager = trustAllCerts();
        return new GRPCSSLContext(trustManager);
    }
}

34、Default过滤器

要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters。该属性接受一个筛选器列表。以下清单定义了一组默认过滤器:

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin

参考资料

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

你可能感兴趣的:(spring,boot,cloud,spring,cloud,gateway,java)