添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

spring cloud 之Gateway使用详解

spring cloud 之Gateway使用详解,从零开始搭建Gateway,进行自定义配置,主要文档内容来源与spring cloud官方文档

Posted by yishuifengxiao on 2019-08-20

Spring Cloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,取代 Zuul 网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

Spring Cloud Gateway 基于 Spring Boot 2.0, Spring WebFlux 和 Project Reactor 构建。因此,许多熟悉的同步库(例如 Spring Data 和 Spring Security)和模式在使用 Spring Cloud Gateway 时可能不适用.

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

一 快速入门

在使用 gateway 之前,需要先明确几个概念

  • Route: 路由是网关的基本构建块。 它由 ID,目标 URI,Predicate 集合和 Filter 集合组成。 如果 Predicate 的结果为真,则匹配路由。
  • Predicate: 这是一个 Java 8 中的 Predicate 函数。 输入类型是 Spring 框架中的 ServerWebExchange 。 这允许开发人员匹配来自 HTTP 请求的任何内容,例如请求头或参数。
  • Filter :这些是使用特定工厂构建的 Spring 框架里的 GatewayFilter 实例。 这里,可以在发送下游请求之前或之后修改请求和响应。
  • 客户端向 Spring Cloud Gateway 发出请求,如果该请求与网关中的路由匹配, ,则将其转发到网关中对应的 Web 处理程序,然后这些请求会被特定的过滤器链处理。

    1.1 加入依赖

    新建一个 spring cloud 项目,在项目的 pom 文件里加入以下依赖

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

    1.2 配置属性

    在属性配置文件里加入以下配置

    server:
    port: 8081

    spring:
    application:
    name: gateway-demo
    cloud:
    gateway:
    discovery:
    locator:
    enabled: true
    lowerCaseServiceId: true

    eureka:
    client:
    service-url:
    defaultZone: http://localhost:8761/eureka/

    spring.cloud.gateway.discovery.locator.enabled true 表明 gateway 开启服务注册和发现的功能,spring cloud gateway 自动根据发现的服务为每一个服务创建了一个 router,这个 router 将以服务名开头的请求路径转发到对应的服务。

    spring.cloud.gateway.discovery.locator.lowerCaseServiceId 是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)

    1.3 自定义路由

    在默认情况下,向网关发送的请求时,url 必须带上服务名 service-demo 这个前缀,才能转发到 service-demo 上,网关会在转发之前会将 service-demo 去掉。

    如果有时候因为项目需求需要自定义转发路径,我们设置自己的转发规则:

    spring:
    application:
    name: gateway-demo
    cloud:
    gateway:
    discovery:
    locator:
    enabled: false
    lowerCaseServiceId: true
    routes:
    - id: service-demo
    uri: lb://SERVICE-DEMO
    predicates:
    - Path=/demo/**
    filters:
    - StripPrefix=1

    在上面的配置中,网关会将以 /demo/** 开头的请求都会转发到 uri 为 lb://SERVICE-DEMO 的地址上,其中 lb://SERVICE-DEMO service-demo 服务的负载均衡地址,并用 StripPrefix filter 在转发之前将 /demo 去掉。

    spring.cloud.gateway.discovery.locator.enabled=false 关闭自动发现功能,如果不改的话,网关就会为每个服务创建两个路由,之前的 localhost:8081/service-demo/hi?name=1323 这样的请求地址也能正常访问。

    二 路由匹配

    Spring Cloud Gateway 将路由作为 Spring WebFlux 的 HandlerMapping 基础结构的一部分进行匹配。 Spring Cloud Gateway 包含许多基于 HTTP 请求的不同属性进行匹配的内置的 Route Predicate 工厂,多个 Predicate 工厂可以通过 与连接 进行组合。

    2.1 After Route Predicate

    After Route Predicate,可配置一个时间,当请求的时间在配置时间之后,才交给 router 去处理

    spring:
    cloud:
    gateway:
    routes:
    - id: after_route
    uri: https://example.org
    predicates:
    - After=2017-01-20T17:42:47.789-07:00[America/Denver]

    2.2 Before Route Predicate

    Before Route Predicate,可配置一个时间,当请求的时间在配置时间之前,才交给 router 去处理

    spring:
    cloud:
    gateway:
    routes:
    - id: before_route
    uri: https://example.org
    predicates:
    - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

    2.3 Between Route Predicate

    Between Route Predicate,可配置两个时间,当请求的时间在配置时间之间,才交给 router 去处理

    spring:
    cloud:
    gateway:
    routes:
    - id: between_route
    uri: https://example.org
    predicates:
    - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

    Cookie Route Predicate Factory 有两个参数,cookie 名称和正则表达式。 此 Predicate 匹配具有给定名称且值与正则表达式匹配的 cookie。

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

    此路由匹配请求有一个名为 chocolate 的 cookie,其值与 ch.p 正则表达式匹配。

    2.5 Header Route Predicate

    Header Route Predicate 工厂采用两个参数,请求头名称和正则表达式。 此 Predicate 与具有给定名称且值与正则表达式匹配的请求头匹配。

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

    如果请求具有名为 X-Request-Id 的请求头,则该路由匹配,其值与 \d+ 正则表达式匹配(具有一个或多个数字的值)

    2.6 Host Route Predicate

    Host Route Predicate Factory 采用一个参数:多个主机名匹配规则。 该匹配模式是一种 . 作为分隔符,采用 Ant 风格匹配。 此 Predicate 匹配与模式匹配的 Host 请求头。

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

    也支持 URI 模板变量,例如 {sub}.myhost.org

    如果请求的主机头具有值 www.somehost.org beta.somehost.org www.anotherhost.org ,则将匹配此路由。

    此 Predicate 将 URI 模板变量(如上例中定义的 sub)提取为名称和值的映射,可以根据键 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE ServerWebExchange.getAttributes() 中获取其中的值,也可以在 GatewayFilter Factories 使用这些值。

    2.7 Method Route Predicate

    Method Route Predicate Factory 采用一个参数:要匹配的 HTTP 方法。

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

    如果请求方法是 GET,则此路由将匹配。

    2.8 Path Route Predicate

    Path Route Predicate Factory 有两个参数:多个的 Spring PathMatcher 匹配规则和可选的 matchOptionalTrailingSeparator 标志。

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

    则此路由将匹配例如: /foo/1 /foo/bar /bar/baz 形式的路径。

    此 Predicate 将 URI 模板变量(如上例中定义的 segment )提取为名称和值的映射,并将其放在 ServerWebExchange.getAttributes() 中,根据键 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 从中获取对应的值,也可以在 GatewayFilter Factories 使用这些值。

    可以使用实用程序方法来更轻松地访问这些变量,调用方法如下。

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

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

    2.9 Query Route Predicate

    Query Route Predicate Factory 有两个参数:一个必需的参数和一个可选的正则表达式。

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

    如果请求包含 baz 查询参数,则此路由将匹配。

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

    如果请求包含其值与 ba 匹配的 foo 查询参数,则此路由将匹配。 regexp,所以 bar 和 baz 匹配。

    2.10 RemoteAddr Route Predicate

    RemoteAddr Route Predicate Factory 采用 CIDR 表示法(IPv4 或 IPv6)字符串的列表(最小值为 1),例如, 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

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

    如果请求的远程地址是例如 192.168.1.10,则此路由将匹配。

    修改远程地址的解析方式
    默认情况下,RemoteAddr Route Predicate Factory 使用传入请求中的远程地址。如果 Spring Cloud Gateway 位于代理层后面,则可能与实际客户端 IP 地址不匹配。

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

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

    XForwardedRemoteAddressResolver::trustAll 返回一个 RemoteAddressResolver ,它始终采用 X-Forwarded-For 请求头中找到的第一个 IP 地址。这种方法容易受到欺骗,因为恶意客户端可以为解析器接受的 X-Forwarded-For 设置初始值。

    XForwardedRemoteAddressResolver::maxTrustedIndex 采用与 Spring Cloud Gateway 前运行的可信基础架构数相关的索引。例如,如果只能通过 HAProxy 访问 Spring Cloud Gateway,则应使用值 1。如果在可访问 Spring Cloud Gateway 之前需要两跳可信基础架构,则应使用值 2。

    三 网关过滤器

    路由过滤器范围限定为特定路径,它允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。

    注意有关如何使用以下任何过滤器的更详细示例,请查看单元测试。

    3.1 AddRequestHeader

    AddRequestHeader GatewayFilter 工厂接受一个名称和值参数。

    spring:
    cloud:
    gateway:
    routes:
    - id: add_request_header_route
    uri: https://example.org
    filters:
    - AddRequestHeader=X-Request-Foo, Bar

    这将为所有匹配请求的下游请求头添加 X-Request-Foo:Bar 请求头。

    3.2 AddRequestParameter

    AddRequestParameter GatewayFilter Factory 采用名称和值参数。

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

    这会将 foo=bar 添加到下游请求的所有匹配请求的查询字符串中。

    3.3 AddResponseHeader

    AddResponseHeader GatewayFilter Factory 采用名称和值参数。

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

    这会将 X-Response-Foo:Bar 请求头添加到所有匹配请求的下游响应标头中。

    3.4 DedupeResponseHeader

    DedupeResponseHeader GatewayFilter Factory 采用名称参数和可选策略参数。 name 可以包含标题名称列表,空格分隔。

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

    在网关 CORS 逻辑和下游添加它们的情况下,这将删除 Access-Control-Allow-Credentials Access-Control-Allow-Origin 响应头的重复值。

    DedupeResponseHeader 过滤器还接受可选的策略参数。 接受的值为 RETAIN_FIRST (默认值), RETAIN_LAST RETAIN_UNIQUE

    3.5 Hystrix

    Hystrix 是一个实现了断路器模式的 Netflix 库。 Hystrix GatewayFilter 允许您将断路器引入网关路由,保护您的服务免受级联故障的影响,并允许您在下游故障时提供回退响应。

    要在项目中启用 Hystrix GatewayFilters,请在 Spring Cloud Netflix 上添加 spring-cloud-starter-netflix-hystrix 的依赖。

    Hystrix GatewayFilter Factory 需要单个名称参数,该参数是 HystrixCommand 的名称。

    spring:
    cloud:
    gateway:
    routes:
    - id: hystrix_route
    uri: https://example.org
    filters:
    - Hystrix=myCommandName

    这将使用一个名为 myCommandName 的 HystrixCommand

    Hystrix 过滤器还可以接受可选的 fallbackUri 参数, fallbackUri 参数目前仅支持 forward:schemed URIs 。 如果调用了回退,则请求将被转发到与 URI 匹配的控制器。

    spring:
    cloud:
    gateway:
    routes:
    - id: hystrix_route
    uri: lb://backing-service:8088
    predicates:
    - Path=/consumingserviceendpoint
    filters:
    - name: Hystrix
    args:
    name: fallbackcmd
    fallbackUri: forward:/incaseoffailureusethis
    - RewritePath=/consumingserviceendpoint, /backingserviceendpoint

    当调用 Hystrix 后备时,这将转发到 /incaseoffailureuset 这个 URI。 请注意,此示例还通过目标 URI 上可选的 lb 前缀实现负载平衡。

    主要方案是将 fallbackUri 用于网关应用程序内的内部控制器或处理程序。 但是,也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:

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

    在此示例中,网关应用程序中没有设置回退端点或处理程序,但是在 http//localhost:9994 下注册的另一个应用程序中进行处理。

    如果请求被转发到回退,Hystrix 网关过滤器还会提供导致它的 Throwable ,并以键名 ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR 存储在 ServerWebExchange 中,从而处理网关应用程序中的回退时使用该属性。

    对于外部控制器/处理程序方案,可以添加包含异常详细信息的请求头。 您可以在 FallbackHeaders GatewayFilter Factory 部分中找到有关它的更多信息。

    Hystrix 设置(例如超时)可以使用全局默认值配置,也可以使用应用程序属性逐个路径配置。

    要为上面的示例路由设置 5 秒超时,将使用以下配置:

    hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000

    3.6 FallbackHeaders

    FallbackHeaders 工厂允许您在转发到外部应用程序中的 fallbackUri 的请求头中添加 Hystrix 执行异常详细信息,如下所示:

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

    在此示例中,在运行 HystrixCommand 时发生执行异常后,会将请求转发到在 localhost:9994 上运行的应用程序中的回退端点或处理程序。 导致异常的异常类型消息和 -if available- root 的请求头会由 FallbackHeaders 过滤器添加到该请求的请求头中。

    通过设置下面列出的参数的值及其默认值,可以在配置中覆盖标头的名称:

    - executionExceptionTypeHeaderName ("Execution-Exception-Type")
    - executionExceptionMessageHeaderName ("Execution-Exception-Message")
    - rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
    - rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")

    3.7 PrefixPath

    PrefixPath GatewayFilter Factory 采用单个前缀参数。

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

    这将匹配到所有以 /mypath 前缀的路径,并将请求 /hello 转发到 /mypath/hello

    3.8 PreserveHostHeader

    PreserveHostHeader GatewayFilter Factory 没有参数。 此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始主机头,而不是 http 客户端确定的主机头。

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

    3.9 RequestRateLimiter

    RequestRateLimiter GatewayFilter Factory 使用 RateLimiter 实现来确定是否允许当前请求继续。 如果不是,则返回 HTTP 429 - Too Many Requests(默认情况下)的状态。

    此过滤器采用可选的 keyResolver 参数和特定于速率限制器的参数(参见下文)。

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

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

    PrincipalNameKeyResolver KeyResolver 的一个默认实现,它从 ServerWebExchange 检索 Principal 并调用 Principal.getName() 。默认情况下,如果 KeyResolver 未找到密钥,则会拒绝请求。

    可以使用 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true 或 false)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 来调整此行为。

    RequestRateLimiter 不能通过“快捷方式”表示法进行配置。 以下示例无效

    # INVALID SHORTCUT CONFIGURATION
    spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

    Redis RateLimiter

    这个 redis 扩展在 Stripe 基础上基于令牌桶算法完成的实现,它需要项目引入 spring-boot-starter-data-redis-reactive 启动器。

    redis-rate-limiter.replenishRate 表示希望允许用户每秒执行多少请求,而不会丢弃任何请求。 这是令牌桶填充的速率。

    redis-rate-limiter.burstCapacity 是用户在一秒钟内允许执行的最大请求数。 这是令牌桶可以容纳的令牌数。 将此值设置为零将阻止所有请求。

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

    spring:
    cloud:
    gateway:
    routes:
    - id: requestratelimiter_route
    uri: https://example.org
    filters:
    - name: RequestRateLimiter
    args:
    redis-rate-limiter.replenishRate: 10
    redis-rate-limiter.burstCapacity: 20

    java 代码

    @Bean
    KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }

    这定义了每个用户 10 的请求率限制。 允许突发 20,但下一秒只有 10 个请求可用。 KeyResolver 是一个简单的获取用户请求参数(注意:这不建议用于生产)。

    速率限制器也可以使用实现 RateLimiter 接口的 bean 来定义, 在配置中使用 SpEL 按名称引用 bean。 #{@ myRateLimiter} 是一个引用名为 myRateLimiter 的 bean 的 SpEL 表达式。

    spring:
    cloud:
    gateway:
    routes:
    - id: requestratelimiter_route
    uri: https://example.org
    filters:
    - name: RequestRateLimiter
    args:
    rate-limiter: "#{@myRateLimiter}"
    key-resolver: "#{@userKeyResolver}"

    3.10 RedirectTo

    RedirectTo GatewayFilter Factory 采用 status url 参数。 状态应该是 300 系列重定向 http 代码,例如 301. url 应该是有效的 URL。 这将是 Location 标头的值。

    spring:
    cloud:
    gateway:
    routes:
    - id: prefixpath_route
    uri: https://example.org
    filters:
    - RedirectTo=302, https://acme.org

    这将发送状态 302,其中包含 Location:https://acme.org 标头以执行重定向。

    3.11 RemoveHopByHopHeaders

    RemoveHopByHopHeadersFilter GatewayFilter Factory 从转发的请求中删除标头。 删除的标头列表来自 IETF。

    默认删除的请求头是:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • 要更改此设置,请将 spring.cloud.gateway.filter.remove-non-proxy-headers.headers 属性设置为要删除的请求头名称列表。

    3.12 RemoveRequestHeader

    RemoveRequestHeader GatewayFilter Factory 采用名称参数。 它的值是要删除的请求头的名称。

    spring:
    cloud:
    gateway:
    routes:
    - id: removerequestheader_route
    uri: https://example.org
    filters:
    - RemoveRequestHeader=X-Request-Foo

    这将在向下游发送之前删除 X-Request-Foo 请求头。

    3.13 RemoveResponseHeader

    RemoveResponseHeader GatewayFilter Factory 采用名称参数。 它是要删除的标头的名称。

    spring:
    cloud:
    gateway:
    routes:
    - id: removeresponseheader_route
    uri: https://example.org
    filters:
    - RemoveResponseHeader=X-Response-Foo

    这将在响应返回到网关客户端之前从响应中删除 X-Response-Foo 标头。

    要删除任何类型的敏感标头,您应该为您可能要执行此操作的任何路由配置此过滤器。 此外,您可以使用 spring.cloud.gateway.default-filters 配置此过滤器并将其应用于所有路由 z 中。

    3.14 RewritePath

    RewritePath GatewayFilter Factory 采用路径正则参数和替换参数。 这使用 Java 正则表达式来灵活地重写请求路径。

    spring:
    cloud:
    gateway:
    routes:
    - id: rewritepath_route
    uri: https://example.org
    predicates:
    - Path=/foo/**
    filters:
    - RewritePath=/foo/(?<segment>.*), /$\{segment}

    对于 /foo/bar 的请求路径,这将在发出下游请求之前将路径设置为 /bar 。 注意由于 YAML 规范, $ 替换为 $\

    3.15 RewriteResponseHeader

    RewriteResponseHeader GatewayFilter Factory 采用名称,正则表达式和替换参数。 它使用 Java 正则表达式以灵活的方式重写响应头值。

    spring:
    cloud:
    gateway:
    routes:
    - id: rewriteresponseheader_route
    uri: https://example.org
    filters:
    - RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***

    对于标题值 /42?user=ford&password=omg!what&flag=rue ,在发出下游请求后,它将被设置为 /42?user=ford&password=***&flag=true 。 由于 YAML 规范,请使用 $\ 表示 $

    3.16 SaveSession

    SaveSession GatewayFilter Factory 在转发下游调用之前强制执行 WebSession::save 操作。 当使用 Spring Session 与懒加载数据之类的东西时需要确保在转发调用之前已保存会话状态。

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

    如果要将 Spring Security 与 Spring Session 集成并且希望确保将安全性详细信息转发到远程进程,则这个配置很关键。

    3.17 SecureHeaders

    SecureHeaders GatewayFilter Factory 为响应添加了许多标头。

    添加以下标头(以及默认值):

    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
    frame-options
    content-type-options
    referrer-policy
    content-security-policy
    download-options
    permitted-cross-domain-policies

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

    示例: spring.cloud.gateway.filter.secure-headers.disable = frame-options,download-options

    3.18 SetPath

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

    spring:
    cloud:
    gateway:
    routes:
    - id: setpath_route
    uri: https://example.org
    predicates:
    - Path=/foo/{segment}
    filters:
    - SetPath=/{segment}

    对于 /foo/bar 的请求路径,这将在发出下游请求之前将路径设置为 /bar

    3.19 SetResponseHeader

    SetResponseHeader GatewayFilter Factory 获取名称和值参数。

    spring:
    cloud:
    gateway:
    routes:
    - id: setresponseheader_route
    uri: https://example.org
    filters:
    - SetResponseHeader=X-Response-Foo, Bar

    此 GatewayFilter 用给定名称替换所有标头,而不是添加。 因此,如果下游服务器包含 X-Response-Foo:1234 响应,则将替换为 X-Response-Foo:Bar ,这是网关客户端将接收的内容。

    3.20 SetStatus

    SetStatus GatewayFilter Factory 采用单个状态参数。 它必须是有效的 HttpStatus , 它可以是整数值 404 或 NOT_FOUND 的枚举字符串表示形式。

    spring:
    cloud:
    gateway:
    routes:
    - id: setstatusstring_route
    uri: https://example.org
    filters:
    - SetStatus=BAD_REQUEST
    - id: setstatusint_route
    uri: https://example.org
    filters:
    - SetStatus=401

    在任何一种情况下,响应的 HTTP 状态都将设置为 401。

    3.21 StripPrefix

    StripPrefix GatewayFilter Factory 采用一个参数,即部件。 parts 参数指示在向下游发送之前从请求中剥离的路径中的部分数。

    spring:
    cloud:
    gateway:
    routes:
    - id: nameRoot
    uri: http://nameservice
    predicates:
    - Path=/name/**
    filters:
    - StripPrefix=2

    当通过网关向 /name/bar/foo 发出请求时,对 nameservice 的请求将转发到 http//nameservice/foo

    3.22 Retry

    Retry GatewayFilter Factory 将重试,状态,方法和系列作为参数。

  • retries:应尝试的重试次数
  • statuses:应该重试的 HTTP 状态代码,使用 org.springframework.http.HttpStatus 表示
  • methods:应该重试的 HTTP 方法,使用 org.springframework.http.HttpMethod 表示
  • series:要重试的一系列状态代码,使用 org.springframework.http.HttpStatus.Series 表示
  • 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

    重试过滤器当前不支持使用正文重试(例如,对于具有正文的 POST 或 PUT 请求)。

    当使用带有转发前缀 URL 的重试过滤器时,应仔细编写目标端点,以便在出现错误时不会执行任何可能导致响应发送到客户端并提交的操作。 例如,如果目标端点是带注释的控制器,则目标控制器方法不应返回带有错误状态代码的 ResponseEntity。 相反,它应抛出异常或发出错误信号,例如 通过 Mono.error(ex) 返回值,可以将重试过滤器配置为通过重试来处理。

    3.23 RequestSize

    当请求大小大于允许的限制时,RequestSize GatewayFilter Factory 可以限制请求到达下游服务。 过滤器将 RequestSize 作为参数,该参数是以字节为单位定义的请求的允许大小限制。

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

    当请求因大小而被拒绝时,RequestSize GatewayFilter Factory 将响应状态设置为 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

    如果未在路由定义中提供过滤器参数,则默认请求大小将设置为 5 MB。

    3.24 ModifyRequestBody

    此过滤器被视为 BETA,API 可能在将来发生变化

    此过滤器可用于在网关向下游发送请求主体之前对其进行修改。

    @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;
    }
    }

    3.25 ModifyResponseBody

    此过滤器被视为 BETA,API 可能在将来发生变化

    此过滤器可用于在将响应主体发送回客户端之前对其进行修改。

    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
    .route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
    .filters(f -> f.prefixPath("/httpbin")
    .modifyResponseBody(String.class, String.class,
    (exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)
    .build();
    }

    3.26 Default Filters

    如果您想添加过滤器并将其应用于所有路线,可以使用 spring.cloud.gateway.default-filters。 此属性采用过滤器列表

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

    四 全局过滤器

    GlobalFilter 接口与 GatewayFilter 具有相同的签名, 这些是有条件地应用于所有路线的特殊过滤器。 (此接口和用法可能会在未来的里程碑中发生变化)。

    4.1 过滤器排序

    当请求进入(并匹配路由)时,Filtering Web Handler 会将 GlobalFilter 的所有实例和 GatewayFilter 的所有路由特定实例添加到过滤器链。 这个组合的过滤器链由 org.springframework.core.Ordered 接口排序,可以通过实现 getOrder() 方法或使用 @Order 注释来设置。

    由于 Spring Cloud Gateway 区分了过滤器逻辑执行的“前”和“后”阶段,第一个前置过滤器和最后一个后置过滤器具有最高优先级。

    @Bean
    @Order(-1)
    public GlobalFilter a() {
    return (exchange, chain) -> {
    log.info("first pre filter");
    return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    log.info("third post filter");
    }));
    };
    }

    @Bean
    @Order(0)
    public GlobalFilter b() {
    return (exchange, chain) -> {
    log.info("second pre filter");
    return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    log.info("second post filter");
    }));
    };
    }

    @Bean
    @Order(1)
    public GlobalFilter c() {
    return (exchange, chain) -> {
    log.info("third pre filter");
    return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    log.info("first post filter");
    }));
    };
    }

    4.2 Forward Routing Filter

    ForwardRoutingFilter 使用键 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 从 exchange 中查找 URI。 如果 url 具有 forward 方案(即 forward:///localendpoint ),它将使用 Spring DispatcherHandler 处理请求。 请求 URL 的路径部分将被转发 URL 中的路径覆盖。 未修改的原始 URL 将追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 属性中的列表中。

    4.3 LoadBalancerClient Filter

    LoadBalancerClientFilter 使用键 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 从 exchange 中查找 URI。 如果 url 具有 lb 方案(即 lb//myservice ),它将使用 Spring Cloud LoadBalancerClient 将名称(前一示例中的 myservice)解析为实际主机和端口,并替换相同属性中的 URI。 未修改的原始 URL 将追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 属性中的列表中。 过滤器还将查看 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 属性以查看它是否等于 lb,然后应用相同的规则。

    spring:
    cloud:
    gateway:
    routes:
    - id: myRoute
    uri: lb://service
    predicates:
    - Path=/service/**

    默认情况下,在 LoadBalancer 中找不到服务实例时,将返回 503。 您可以通过设置 spring.cloud.gateway.loadbalancer.use404 = true 来配置网关以返回 404。

    从 LoadBalancer 返回的 ServiceInstance isSecure 值将覆盖在对网关发出的请求中指定的方案。 例如,如果请求通过 HTTPS 进入网关但 ServiceInstance 指示它不安全,则下游请求将通过 HTTP 进行。 相反的情况也适用。 但是,如果为网关配置中的路由指定了 GATEWAY_SCHEME_PREFIX_ATTR ,则将剥离前缀,并且路由 URL 中的结果方案将覆盖 ServiceInstance 配置。

    4.4 Netty Routing Filter

    如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性中的 URL 具有 http 或 https 方案,则运行 Netty 路由过滤器。 它使用 Netty HttpClient 发出下游代理请求。 响应放在 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中,以便在以后的过滤器中使用。 (有一个实验性的 WebClientHttpRoutingFilter 执行相同的功能,但不需要 netty)

    4.5 Netty Write Response Filter

    如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中存在 Netty HttpClientResponse,则运行 NettyWriteResponseFilter 。 它在所有其他过滤器完成后运行,并将代理响应写回网关客户端响应。 (有一个实验性的 WebClientWriteResponseFilter 执行相同的功能,但不需要 netty)

    4.6 RouteToRequestUrl Filter

    如果 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 交换属性中存在 Route 对象,则运行 RouteToRequestUrlFilter。 它根据请求 URI 创建一个新 URI,但使用 Route 对象的 URI 属性进行更新。 新 URI 放在 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性`中。

    如果 URI 具有方案前缀,例如 lb:ws:// serviceid ,则 lb 方案将从 URI 中剥离并放置在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 中,以便稍后在过滤器链中使用。

    4.7 Websocket Routing Filter

    如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性中的 URL 具有 ws 或 wss 方案,则运行 Websocket 路由过滤器。 它使用 Spring Web Socket 基础结构将 Websocket 请求转发到下游。

    可以通过在 URI 前面添加 lb 来对 Websockets 进行负载平衡,例如 lb:ws//serviceid

    如果您使用 SockJS 作为普通 http 的后备,则应配置正常的 HTTP 路由以及 Websocket 路由。

    spring:
    cloud:
    gateway:
    routes:
    # SockJS route
    - id: websocket_sockjs_route
    uri: http://localhost:3001
    predicates:
    - Path=/websocket/info/**
    # Normwal Websocket route
    - id: websocket_route
    uri: ws://localhost:3001
    predicates:
    - Path=/websocket/**

    4.8 Gateway Metrics Filter

    要启用 Gateway Metrics,请将 spring-boot-starter-actuator 添加为项目依赖项。 然后,默认情况下,只要属性 spring.cloud.gateway.metrics.enabled 未设置为 false ,网关指标筛选器就会运行。 此过滤器添加名为“gateway.requests”的计时器度量标准,其中包含以下标记:

    routeId:路由ID
    routeUriAPI将路由到的URI
    outcome:由HttpStatus.Series分类的结果
    statusHttp返回给客户端的请求状态
    httpStatusCode:返回给客户端的请求的Http状态
    httpMethod:用于请求的Http方法

    然后可以从 /actuator/metrics/gateway.requests 中删除这些指标,并可以轻松地与 Prometheus 集成以创建 Grafana 仪表板。

    要启用 pometheus 端点,请将 micrometer-registry-prometheus 添加为项目依赖项。

    4.9 Marking An Exchange As Routed

    在 Gateway 路由了 ServerWebExchange 之后,它会通过将 gatewayAlreadyRouted 添加到 exchange 属性来将该交换标记为“路由”。 一旦请求被标记为路由,其他路由过滤器将不会再次路由请求,实质上是跳过过滤器。 您可以使用便捷方法将交换标记为路由,或检查交换是否已路由。

    ServerWebExchangeUtils.isAlreadyRouted 接受 ServerWebExchange 对象并检查它是否已“路由”
    ServerWebExchangeUtils.setAlreadyRouted 接受 ServerWebExchange 对象并将其标记为“路由”

    5 进阶配置

    Spring Cloud Gateway 的配置由 RouteDefinitionLocator s 的集合驱动。

    public interface RouteDefinitionLocator {
    Flux<RouteDefinition> getRouteDefinitions();
    }

    默认情况下,PropertiesRouteDefinitionLocator 使用 Spring Boot 的@ConfigurationProperties 机制加载属性。

    上面的配置示例都使用了一个使用位置参数而不是命名参数的快捷符号。 以下两个例子是等效的:

    spring:
    cloud:
    gateway:
    routes:
    - id: setstatus_route
    uri: https://example.org
    filters:
    - name: SetStatus
    args:
    status: 401
    - id: setstatusshortcut_route
    uri: https://example.org
    filters:
    - SetStatus=401

    对于网关的一些用法,属性是足够的,但是一些生产用例将受益于从外部源(例如数据库)加载配置。 未来的里程碑版本将具有基于 Spring Data Repositories 的 RouteDefinitionLocator 实现,例如:Redis,MongoDB 和 Cassandra。

    5.1 流式路由配置

    为了允许在 Java 中进行简单配置,在 RouteLocatorBuilder bean 中定义了一个流式的 API。

    // static imports from GatewayFilters and RoutePredicates
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
    return builder.routes()
    .route(r -> r.host("**.abc.org").and().path("/image/png")
    .filters(f ->
    f.addResponseHeader("X-TestHeader", "foobar"))
    .uri("http://httpbin.org:80")
    )
    .route(r -> r.path("/image/webp")
    .filters(f ->
    f.addResponseHeader("X-AnotherHeader", "baz"))
    .uri("http://httpbin.org:80")
    )
    .route(r -> r.order(-1)
    .host("**.throttle.org").and().path("/get")
    .filters(f -> f.filter(throttle.apply(1,
    1,
    10,
    TimeUnit.SECONDS)))
    .uri("http://httpbin.org:80")
    )
    .build();
    }

    此样式还允许更多自定义谓词断言。 RouteDefinitionLocator bean 定义的谓词使用逻辑和组合。 通过使用流畅的 Java API,您可以在 Predicate 类上使用 and(),或()和 negate()运算符。

    5.2 由定义定位器

    可以将网关配置为基于在 DiscoveryClient 兼容服务注册中心注册的服务来创建路由。

    要启用此功能,请设置 spring.cloud.gateway.discovery.locator.enabled = true 并确保 DiscoveryClient 实现位于类路径上并已启用(例如 Netflix Eureka,Consul 或 Zookeeper)。

    默认情况下,Gateway 为通过 DiscoveryClient 创建的路由定义单个 Predicate 和过滤器。

    默认 Predicate 是使用模式 /serviceId/** 定义的路径 Predicate,其中 serviceId 是 DiscoveryClient 中服务的 id。

    默认过滤器是重写路径过滤器,其中包含正则表达式 /serviceId/(?<remaining>.*) 和替换 /${remaining} 。 这只是在向下游发送请求之前从路径中剥离服务 ID。

    如果您想自定义 DiscoveryClient 路由使用的 Predicate,可以通过设置 spring.cloud.gateway.discovery.locator.predicates [x] spring.cloud.gateway.discovery.locator.filters[Y] 来实现。 执行此操作时,如果要保留该功能,则需要确保包含上面的默认 Predicate 和过滤器。 下面是一个这样的例子。

    spring.cloud.gateway.discovery.locator.predicates[0].name: Path
    spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
    spring.cloud.gateway.discovery.locator.predicates[1].name: Host
    spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
    spring.cloud.gateway.discovery.locator.filters[0].name: Hystrix
    spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
    spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
    spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/(?<remaining>.*)'"
    spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

    5.3 Reactor Netty 访问日志

    要启用 Reactor Netty 访问日志,请设置 -Dreactor.netty.http.server.accessLogEnabled = true 。 (它必须是 Java System 属性,而不是 Spring Boot 属性)。

    可以将日志记录系统配置为具有单独的访问日志文件。 以下是一个示例 logback 配置:

    <appender name="accessLog" class="ch.qos.logback.core.FileAppender">
    <file>access_log.log</file>
    <encoder>
    <pattern>%msg%n</pattern>
    </encoder>
    </appender>
    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="accessLog" />
    </appender>

    <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
    <appender-ref ref="async"/>
    </logger>

    5.4 跨域设置

    网关可以配置为控制 CORS 行为。 “全局”CORS 配置是 Spring Framework CorsConfiguration 的 URL 模式映射。

    spring:
    cloud:
    gateway:
    globalcors:
    corsConfigurations:
    '[/**]':
    allowedOrigins: "https://docs.spring.io"
    allowedMethods:
    - GET

    在上面的示例中,对于所有 GET 请求的路径,将允许来自 docs.spring.io 的请求的 CORS 请求。

    5.5 Actuator API

    gateway 执行器端点允许监视 Spring Cloud Gateway 应用程序并与之交互。 要进行远程访问,必须在应用程序属性中通过 HTTP 或 JMX 启用和公开端点。

    management.endpoint.gateway.enabled=true # default value
    management.endpoints.web.exposure.include=gateway
    5.5.1 查看全局过滤器

    要检索应用于所有路由的全局过滤器,请向/ actuator / gateway / globalfilters 发出 GET 请求。 结果响应类似于以下内容:

    {
    "org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5": 10100,
    "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,
    "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,
    "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,
    "org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,
    "org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,
    "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,
    "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
    }

    响应包含有关全局过滤器的详细信息。 对于每个全局过滤器,提供过滤器对象的字符串表示(例如, org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5 )以及过滤器链中的相应顺序。

    5.5.2 路由过滤器

    要检索应用于路由的 GatewayFilter 工厂,请向 /actuator/gateway/routefilters 发出 GET 请求。 结果响应类似于以下内容:

    {
    "[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
    "[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
    }

    响应包含应用于任何特定路由的 GatewayFilter 工厂的详细信息。 为每个工厂提供相应对象的字符串表示(例如,[ SecureHeadersGatewayFilterFactory @ fceab5d configClass = Object] )。 请注意,null 值是由于端点控制器的实现不完整,因为它尝试设置过滤器链中对象的顺序,这不适用于 GatewayFilter 工厂对象。

    5.5.3 刷新路由缓存

    要清除路由缓存,请对 /actuator/gateway/refresh 发出 POST 请求。 请求返回 200 且没有响应正文。

    5.5.4 检索网关中定义的路由

    要检索网关中定义的路由,请对 /actuator/gateway/routes 发出 GET 请求。 结果响应类似于以下内容:

    [{
    "route_id": "first_route",
    "route_object": {
    "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d",
    "filters": [
    "OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"
    ]
    },
    "order": 0
    },
    {
    "route_id": "second_route",
    "route_object": {
    "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
    "filters": []
    },
    "order": 0
    }]

    响应包含网关中定义的所有路由的详细信息。 下表描述了响应的每个元素(即路由)的结构。

    5.5.5 检索有关特定路线的信息

    要检索有关单个路由的信息,请向 /actuator/gateway/routes/{id} 发出 GET 请求(例如, /actuator/gateway/routes/first_route )。 结果响应类似于以下内容:

    {
    "id": "first_route",
    "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/first"}
    }],
    "filters": [],
    "uri": "https://www.uri-destination.org",
    "order": 0
    }]
    5.5.6 创建和删除特定路线

    要创建路由,请使用指定路由字段的 JSON 主体向 /gateway/routes/{id_route_to_create} 发出 POST 请求。

    要删除路由,请对 /gateway/routes/{id_route_to_delete} 发出 DELETE 请求。

    六 开发文档

    6.1 自定义 GatewayFilter

    为了编写 GatewayFilter,您需要实现 GatewayFilterFactory 。 有一个名为 AbstractGatewayFilterFactory 的抽象类,您可以扩展它。

    public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory() {
    super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
    // grab configuration from Config object
    return (exchange, chain) -> {
    //If you want to build a "pre" filter you need to manipulate the
    //request before calling chain.filter
    ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
    //use builder to manipulate the request
    return chain.filter(exchange.mutate().request(request).build());
    };
    }

    public static class Config {
    //Put the configuration properties for your filter here
    }

    }
    public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory() {
    super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
    // grab configuration from Config object
    return (exchange, chain) -> {
    return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    ServerHttpResponse response = exchange.getResponse();
    //Manipulate the response in some way
    }));
    };
    }

    public static class Config {
    //Put the configuration properties for your filter here
    }

    }

    6.2 自定义全局过滤器

    要编写自定义全局过滤器,您需要实现 GlobalFilter 接口。 这将过滤器应用于所有请求。

    @Bean
    public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
    .map(Principal::getName)
    .defaultIfEmpty("Default User")
    .map(userName -> {
    //adds header to proxied request
    exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
    return exchange;
    })
    .flatMap(chain::filter);
    }

    @Bean
    public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
    .then(Mono.just(exchange))
    .map(serverWebExchange -> {
    //adds header to response
    serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
    HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
    return serverWebExchange;
    })
    .then();
    }

    6.3 使用 Spring MVC 或 Webflux 构建简单网关

    Spring Cloud Gateway 提供了一个名为 ProxyExchange 的实用程序对象,您可以在常规 Spring Web 处理程序中将其用作方法参数。 它通过镜像 HTTP Predicate 的方法支持基本的下游 HTTP 交换。 使用 MVC,它还支持通过 forward() 方法转发到本地处理程序。 要使用 ProxyExchange ,只需在类路径中包含正确的模块( spring-cloud-gateway-mvc spring-cloud-gateway-webflux )。

    MVC 示例(代理向远程服务器下游 /test 的请求):

    @RestController
    @SpringBootApplication
    public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
    return proxy.uri(home.toString() + "/image/png").get();
    }

    }

    Webflux 也是如此:

    @RestController
    @SpringBootApplication
    public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
    return proxy.uri(home.toString() + "/image/png").get();
    }

    }

    ProxyExchange 上有一些便捷方法,使处理程序方法能够发现和增强传入请求的 URI 路径。 例如,您可能希望提取路径的尾随元素以将其传递到下游:

    @GetMapping("/proxy/path/**")
    public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
    String path = proxy.path("/proxy/path/");
    return proxy.uri(home.toString() + "/foos/" + path).get();
    }

    Spring MVC 或 Webflux 的所有功能都可用于 Gateway 处理程序方法。 例如,您可以注入请求标头和查询参数,并且您可以使用映射注释中的声明来约束传入的请求。 有关这些功能的更多详细信息,请参阅 Spring MVC 中的 @RequestMapping 文档。

    可以使用 ProxyExchange 上的 header() 方法将请求头添加到下游响应中。

    您还可以通过向 get() 等方法添加映射器来操作响应标头(以及响应中您喜欢的任何其他内容)。 映射器是一个 Function,它接收传入的 ResponseEntity 并将其转换为传出的 ResponseEntity

    网关支持为“敏感”请求头题(默认情况下为“cookie”和“authorization”)提供了一流的支持,这些标题不向下游传递,也为“代理”请求头( x-forwarded- * )提供。

    Contents
    1. 1. 一 快速入门
      1. 1.1. 1.1 加入依赖
      2. 1.2. 1.2 配置属性
      3. 1.3. 1.3 自定义路由
    2. 2. 二 路由匹配
      1. 2.1. 2.1 After Route Predicate
      2. 2.2. 2.2 Before Route Predicate
      3. 2.3. 2.3 Between Route Predicate
      4. 2.4. 2.4 Cookie Route Predicate
      5. 2.5. 2.5 Header Route Predicate
      6. 2.6. 2.6 Host Route Predicate
      7. 2.7. 2.7 Method Route Predicate
      8. 2.8. 2.8 Path Route Predicate
      9. 2.9. 2.9 Query Route Predicate
      10. 2.10. 2.10 RemoteAddr Route Predicate
    3. 3. 三 网关过滤器
      1. 3.1. 3.1 AddRequestHeader
      2. 3.2. 3.2 AddRequestParameter
      3. 3.3. 3.3 AddResponseHeader
      4. 3.4. 3.4 DedupeResponseHeader
      5. 3.5. 3.5 Hystrix
      6. 3.6. 3.6 FallbackHeaders
      7. 3.7. 3.7 PrefixPath
      8. 3.8. 3.8 PreserveHostHeader
      9. 3.9. 3.9 RequestRateLimiter
      10. 3.10. 3.10 RedirectTo
      11. 3.11. 3.11 RemoveHopByHopHeaders
      12. 3.12. 3.12 RemoveRequestHeader
      13. 3.13. 3.13 RemoveResponseHeader
      14. 3.14. 3.14 RewritePath
      15. 3.15. 3.15 RewriteResponseHeader
      16. 3.16. 3.16 SaveSession
      17. 3.17. 3.17 SecureHeaders
      18. 3.18. 3.18 SetPath
      19. 3.19. 3.19 SetResponseHeader
      20. 3.20. 3.20 SetStatus
      21. 3.21. 3.21 StripPrefix
      22. 3.22. 3.22 Retry
      23. 3.23. 3.23 RequestSize
      24. 3.24. 3.24 ModifyRequestBody
      25. 3.25. 3.25 ModifyResponseBody
      26. 3.26. 3.26 Default Filters
    4. 4. 四 全局过滤器
      1. 4.1. 4.1 过滤器排序
      2. 4.2. 4.2 Forward Routing Filter
      3. 4.3. 4.3 LoadBalancerClient Filter
      4. 4.4. 4.4 Netty Routing Filter
      5. 4.5. 4.5 Netty Write Response Filter
      6. 4.6. 4.6 RouteToRequestUrl Filter
      7. 4.7. 4.7 Websocket Routing Filter
      8. 4.8. 4.8 Gateway Metrics Filter
      9. 4.9. 4.9 Marking An Exchange As Routed
    5. 5. 5 进阶配置
      1. 5.1. 5.1 流式路由配置
      2. 5.2. 5.2 由定义定位器
      3. 5.3. 5.3 Reactor Netty 访问日志
      4. 5.4. 5.4 跨域设置
      5. 5.5. 5.5 Actuator API
        1. 5.5.1. 5.5.1 查看全局过滤器
        2. 5.5.2. 5.5.2 路由过滤器
        3. 5.5.3. 5.5.3 刷新路由缓存
        4. 5.5.4. 5.5.4 检索网关中定义的路由
        5. 5.5.5. 5.5.5 检索有关特定路线的信息
        6. 5.5.6. 5.5.6 创建和删除特定路线
    6. 6. 六 开发文档
      1. 6.1. 6.1 自定义 GatewayFilter
      2. 6.2. 6.2 自定义全局过滤器
      3. 6.3. 6.3 使用 Spring MVC 或 Webflux 构建简单网关