spring cloud gateway介绍

2.2.1.BUILD-SNAPSHOT

该项目提供了一个在Spring生态系统之上构建的API网关,包括:Spring 5,Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注,例如:安全性,监视/指标和弹性。

1. 如何包括Spring Cloud Gateway

要将Spring Cloud Gateway包含在您的项目中,请使用具有组org.springframework.cloud 和工件ID 的启动器spring-cloud-starter-gateway。有关 使用当前Spring Cloud Release Train设置构建系统的详细信息,请参见Spring Cloud Project页面。

如果包括启动器,但是由于某种原因,您不希望启用网关,请设置spring.cloud.gateway.enabled=false。

术语

  • Route:路由网关的基本构建块。它由ID,目标URI,判断集合和过滤器集合定义。如果聚合判断为true,则匹配路由。
  • 判断:这是Java 8 Function判断。输入类型是Spring FrameworkServerWebExchange。这使开发人员可以匹配HTTP请求中的所有内容,例如标头或参数。
  • Filter:这些是使用特定工厂构建的Spring FrameworkGatewayFilter实例。在此,可以在发送下游请求之前或之后修改请求和响应。

3. 工作原理

客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序运行通过特定于请求的筛选器链发送请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前或之后执行逻辑。执行所有“前置”过滤器逻辑,然后发出代理请求。发出代理请求后,将执行“发布”过滤器逻辑。

4. 路由判断工厂

Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些判断都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以合并,也可以通过逻辑合并and。

4.1 后路线判断工厂

After Route Predicate Factory采用一个参数,即日期时间。该判断匹配在当前日期时间之后发生的请求。

application.yml

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

此路线与2017年1月20日17:42山区时间(丹佛)之后的所有请求匹配。

4.2。路线判断工厂之前

路由判断前工厂采用一个参数,即日期时间。该判断匹配当前日期时间之前发生的请求。

application.yml

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

此路线与2017年1月20日17:42山区时间(丹佛)之前的所有请求匹配。

4.3 路线判断工厂之间

路由判断间工厂之间有两个参数,datetime1和datetime2。该判断匹配在datetime1之后和datetime2之前发生的请求。datetime2参数必须在datetime1之后。

application.yml

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]

该路线与2017年1月20日山区时间(丹佛)之后和2017年1月21日17:42山区时间(丹佛)之后的所有请求匹配。这对于维护时段可能很有用。

4.4 .Cookie路线判断工厂

Cookie Route Predicate Factory采用两个参数,即cookie名称和正则表达式。该判断匹配具有给定名称的cookie,并且值匹配正则表达式。

application.yml

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

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

4.5 标头路由判断工厂

标头路由判断工厂采用两个参数,标头名称和正则表达式。该判断与具有给定名称的标头匹配,并且值与正则表达式匹配。

application.yml

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

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

4.6 主机路由判断工厂

主机路由判断工厂采用一个参数:主机名模式列表。该模式是带有.作为分隔符的Ant样式的模式。判断与Host匹配模式的标头匹配。

application.yml

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

还支持URI模板变量{sub}.myhost.org。

如果请求的Host标头中包含值www.somehost.orgor beta.somehost.org或,则此路由将匹配www.anotherhost.org。
该判断提取URI模板变量(sub如上例中定义的那样)作为名称和值的映射,并ServerWebExchange.getAttributes()使用中定义的键将其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。这些值可供GatewayFilter工厂使用。

4.7 方法路线判断工厂

方法路由判断工厂使用一个参数:要匹配的HTTP方法。

application.yml

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

如果request方法为,则此路由将匹配GET

4.8 路径路线判断工厂

路径路由判断工厂具有两个参数:弹簧PathMatcher模式列表和的可选标志matchOptionalTrailingSeparator。
application.yml

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

如果请求路径是,例如这条路线将匹配:/foo/1或/foo/bar或/bar/baz。

该判断提取URI模板变量(segment如上例中定义的那样)作为名称和值的映射,并ServerWebExchange.getAttributes()使用中定义的键将其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。这些值可供GatewayFilter工厂使用。

可以使用实用程序方法来简化对这些变量的访问

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

4.9 查询路由判断工厂

查询路由判断工厂采用两个参数:required param和optional regexp。

application.yml

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

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

application.yml

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

如果请求包含一个foo查询参数,其值与ba.regexp 匹配,则此路由将匹配,bar并且baz将匹配。

4.10 RemoteAddr路由判断工厂

RemoteAddr路由判断工厂采用CIDR表示法(IPv4或IPv6)字符串的列表(最小大小为1),例如192.168.0.1/16(其中192.168.0.1IP地址16为子网掩码)。
application.yml

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

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

4.10 重量路线判断工厂

权重路由判断工厂采用两个参数组和权重。权重是按组计算的。
application.yml

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%的流量转发至weighthigh.org,并将约20%的流量转发至weightlow.org。

4.11 .1 修改远程地址的解析方式

默认情况下,RemoteAddr路由判断工厂使用传入请求中的远程地址。如果Spring Cloud Gateway位于代理层后面,则此地址可能与实际的客户端IP地址不匹配。
您可以通过设置custom来定制解析远程地址的方式RemoteAddressResolver。 Spring Cloud Gateway 来与基于脱一个非默认的远程地址解析器的X -转发,对于头,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。

给定以下标头值:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

maxTrustedIndex下面的值将产生以下远程地址。

maxTrustedIndex结果
[ Integer.MIN_VALUE,0]IllegalArgumentException在初始化期间无效)
1个0.0.0.3
20.0.0.2
30.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")
)

5 GatewayFilter工厂

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

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

5.1 AddRequestHeader GatewayFilter工厂

AddRequestHeader GatewayFilter工厂采用名称和值参数。
application.yml

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

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

AddRequestHeader知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。

application.yml

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

5.2 AddRequestParameter GatewayFilter工厂

AddRequestParameter GatewayFilter工厂采用名称和值参数。

application.yml

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

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

AddRequestParameter知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。

application.yml

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

5.3 AddResponseHeader GatewayFilter工厂

AddResponseHeader GatewayFilter工厂采用名称和值参数。

application.yml

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

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

AddResponseHeader知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}

5.4 DedupeResponseHeader GatewayFilter工厂

DedupeResponseHeader GatewayFilter工厂采用一个name参数和一个可选strategy参数。name可以包含标题名称列表,以空格分隔。

application.yml

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-CredentialsAccess-Control-Allow-Origin响应标头,则这将删除它们。

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

5.5Hystrix GatewayFilter工厂

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

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

Hystrix GatewayFilter工厂需要一个name参数,它是的名称HystrixCommand

application.yml

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

这会将其余的过滤器包装在HystrixCommand带有命令名的中myCommandName

Hystrix过滤器还可以接受可选fallbackUri参数。当前,仅forward:支持计划的URI。如果调用了后备,则请求将被转发到与URI相匹配的控制器。

application.yml

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

/incaseoffailureusethis调用Hystrix后备时,它将转发到URI。请注意,此示例还通过lb目标URI 上的前缀演示了(可选)Spring Cloud Netflix Ribbon负载平衡。

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

application.yml

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

在此示例中,fallback网关应用程序中没有终结点或处理程序,但是另一个应用程序中有一个终结点或处理程序,在下注册localhost:9994

如果将请求转发给后备,则Hystrix网关过滤器还会提供Throwable引起请求的。它已ServerWebExchange作为 ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR属性添加到,可以在网关应用程序中处理后备时使用。

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

Hystrix设置(例如超时)可以使用全局默认值配置,也可以使用Hystrix Wiki上说明的应用程序属性在逐条路由的基础上进行配置。

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

application.yml

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

5.6 Spring Cloud CircuitBreaker GatewayFilter工厂

Spring Cloud CircuitBreaker过滤器工厂利用Spring Cloud CircuitBreaker API将网关路由包装在断路器中。Spring Cloud CircuitBreaker支持可与Spring Cloud Gateway一起使用的两个库Hystrix和Resilience4J。由于Netflix将Hystrix置于仅维护模式,因此我们建议您使用Resilience4J。

要启用Spring Cloud CircuitBreaker过滤器,您将需要放置spring-cloud-starter-circuitbreaker-reactor-resilience4j或 spring-cloud-starter-netflix-hystrix放置在类路径上。

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

要配置断路器,请参阅所使用的基础断路器实现的配置。

Spring Cloud CircuitBreaker过滤器也可以接受可选fallbackUri参数。当前,仅forward:支持计划的URI。如果调用了后备,则请求将被转发到与URI相匹配的控制器。

application.yml

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调用断路器后备时,它将转发到URI。请注意,此示例还通过lb目标URI 上的前缀演示了(可选)Spring Cloud Netflix Ribbon负载平衡。

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

application.yml

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

在此示例中,fallback网关应用程序中没有终结点或处理程序,但是另一个应用程序中有一个终结点或处理程序,在下注册localhost:9994

如果将请求转发给后备,则Spring Cloud CircuitBreaker网关过滤器还会提供Throwable引起请求的。它已ServerWebExchange作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR属性添加到,可以在网关应用程序中处理后备时使用。

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

5.7 FallbackHeaders GatewayFilter工厂

该FallbackHeaders工厂可以让你在转发到请求的头部添加Hystrix or Spring Cloud CircuitBreaker执行异常的详细信息fallbackUri在以下情况下在外部应用程序,如:

application.yml

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

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

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

有关circuit beakers 和网关的更多信息,请参见Hystrix GatewayFilter Factory部分Spring Cloud CircuitBreaker Factory部分

5.8。MapRequestHeader GatewayFilter工厂

MapRequestHeader GatewayFilter工厂采用’fromHeader’和’toHeader’参数。它创建一个新的命名标头(toHeader),并从传入的HTTP请求中从现有的命名标头(fromHeader)中提取值。如果输入标头不存在,则过滤器不起作用。如果新的命名标头已经存在,则其值将使用新值进行扩充。

application.yml

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

这会将X-Request-Foo:<values>标头添加到下游请求的标头中,其中包含来自传入的HTTP请求Bar标头的更新值。

5.9 PrefixPath GatewayFilter工厂

PrefixPath GatewayFilter工厂采用单个prefix参数。

application.yml

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

这将/mypath作为所有匹配请求的路径的前缀。因此,对的请求/hello将发送给/mypath/hello

5.10PreserveHostHeader GatewayFilter工厂

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

application.yml

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

5.11 RequestRateLimiter GatewayFilter工厂

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

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

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

KeyResolver.java

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

KeyResolver接口允许可插拔策略派生用于限制请求的密钥。在未来的里程碑中,将有一些KeyResolver实现。

的默认实现KeyResolver是,PrincipalNameKeyResolverPrincipalServerWebExchange和调用检索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属性来调整此行为。

application.properties

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

5.11.1。Redis RateLimiter

redis实现基于Stripe所做的工作。它需要使用spring-boot-starter-data-redis-reactiveSpring Boot启动器。

使用的算法是令牌桶算法

redis-rate-limiter.replenishRate是多么的每秒许多请求你希望用户被允许做,没有任何下降的请求。这是令牌桶被填充的速率。

redis-rate-limiter.burstCapacity是允许用户在一个单一的第二做请求的最大数目。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。

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

application.yml

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

配置文件

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

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

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

application.yml

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

5.12 重定向到GatewayFilter工厂

RedirectTo GatewayFilter工厂采用statusurl参数。状态应该是300系列重定向http代码,例如301。URL应该是有效的URL。这将是Location标题的值。

application.yml

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

application.yml

这将发送带有Location:https://acme.org标头的状态302 以执行重定向。

5.13。RemoveHopByHopHeadersFilter GatewayFilter工厂

RemoveHopByHopHeadersFilter GatewayFilter工厂从转发的请求中删除标头。被删除的头的默认列表来自IETF

默认删除的标题是:

  • 连接
  • 活着
  • 代理验证
  • 代理授权
  • TE
  • 预告片
  • 传输编码
  • 升级

要更改此设置,请将spring.cloud.gateway.filter.remove-non-proxy-headers.headers属性设置为要删除的标题名称列表。

5.14。RemoveRequestHeader GatewayFilter工厂

RemoveRequestHeader GatewayFilter工厂采用一个name参数。它是要删除的标题的名称。

application.yml

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

这将删除X-Request-Foo标头,然后再将其发送到下游。

5.15。RemoveResponseHeader GatewayFilter工厂

RemoveResponseHeader GatewayFilter工厂采用一个name参数。它是要删除的标题的名称。

application.yml

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

这将从X-Response-Foo响应中删除标头,然后将其返回到网关客户端。

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

6.全局过滤器

GlobalFilter接口具有与相同的签名GatewayFilter。这些是特殊过滤器,有条件地应用于所有路由。(此界面和用法可能会在将来的里程碑中更改)。

6.1。全局过滤器和GatewayFilter的组合订购

当请求进入(并与路由匹配)时,过滤Web处理程序会将的所有实例GlobalFilter和所有特定GatewayFilter于路由的实例添加到过滤器链中。该组合的过滤器链按org.springframework.core.Ordered接口排序,可以通过实现该getOrder()方法进行设置。

由于Spring Cloud Gateway区分了执行过滤器逻辑的“前”阶段和“后”阶段(请参阅:工作原理),因此优先级最高的过滤器将在“前”阶段中处于第一个阶段,而在“后”阶段中处于最后一个阶段“-相。

ExampleConfiguration.java

@Bean
public GlobalFilter customFilter() {
    return CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

6.2。正向路由过滤器

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

6.3。LoadBalancerClient筛选器

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

application.yml

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

6.4。ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter在交换属性查找一个URI ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR。如果url有一个lb方案(即lb://myservice),它将使用Spring Cloud ReactorLoadBalancer将名称(myservice在前面的示例中)解析为实际的主机和端口,并在同一属性中替换URI。未经修改的原始url将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性中的列表。过滤器还将在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性中查找是否相等 lb,然后应用相同的规则。

application.yml

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

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

从返回 的isSecure值将覆盖对网关的请求中指定的方案。例如,如果请求通过网关进入网关, 但指示该请求不安全,则将通过下游请求 。相反的情况也可以适用。但是,如果在“网关”配置中为路由指定了该前缀,则将删除前缀,并且从路由URL生成的方案将覆盖该配置。 ServiceInstance``ReactiveLoadBalancerClientFilter``HTTPS``ServiceInstance``HTTP``GATEWAY_SCHEME_PREFIX_ATTR``ServiceInstance

6.5。网络路由过滤器

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中的URL 具有httphttps方案,则将运行Netty路由筛选器。它使用Netty HttpClient发出下游代理请求。响应将放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTRexchange属性中,以供以后的过滤器使用。(有一个WebClientHttpRoutingFilter执行相同功能的实验,但不需要净值)

6.6。净写响应过滤器

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

6.7。RouteToRequestUrl过滤器

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

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

6.8。Websocket路由过滤器

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

的WebSockets可以是负载平衡用前缀的URI lb,如lb:ws://serviceid。
如果您将SockJS用作常规http的后​​备,则应配置常规HTTP路由以及Websocket路由。
application.yml

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/**

6.9。网关指标过滤器

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

  • routeId:路线ID
  • routeUri:API将被路由到的URI
  • outcome:按HttpStatus.Series分类的结果
  • status:请求返回给客户端的Http状态
  • httpStatusCode:请求返回给客户端的Http状态
  • httpMethod:用于请求的Http方法

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

6.10。将交换标记为已路由

网关路由完成后,ServerWebExchange它将通过添加gatewayAlreadyRouted 到交换属性来将该交换标记为“已路由” 。将请求标记为已路由后,其他路由筛选器将不会再次路由请求,实质上会跳过该筛选器。您可以使用方便的方法将交换标记为已路由或检查交换是否已路由。

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

7. TLS / SSL

网关可以通过遵循常规的Spring服务器配置来侦听https上的请求。例:

application.yml

server:
  ssl:
    enabled: true
    key-alias: scg
    key-store-password: scg1234
    key-store: classpath:scg-keystore.p12
    key-store-type: PKCS12

网关路由可以同时路由到http和https后端。如果路由到https后端,则可以使用以下配置将网关配置为信任所有下游证书:

application.yml

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          useInsecureTrustManager: true

使用不安全的信任管理器不适用于生产。对于生产部署,可以使用以下配置为网关配置一组可以信任的已知证书:

application.yml

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          trustedX509Certificates:
          - cert1.pem
          - cert2.pem

如果未为Spring Cloud Gateway提供受信任的证书,则使用默认的信任存储(可以用系统属性javax.net.ssl.trustStore覆盖)。

7.1。TLS握手

网关维护用于路由到后端的客户端池。通过https进行通信时,客户端会启动TLS握手。许多超时与此握手相关联。可以配置以下超时(显示默认值):

application.yml

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          handshake-timeout-millis: 10000
          close-notify-flush-timeout-millis: 3000
          close-notify-read-timeout-millis: 0

8.配置

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

RouteDefinitionLocator.java

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

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

上面的所有配置示例都使用一种快捷方式符号,该快捷方式符号使用位置参数而不是命名参数。以下两个示例是等效的:

application.yml

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

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

9.路由元数据配置

可以使用元数据为每个路由配置其他参数:

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: route_with_metadata
        uri: https://example.org
        metadata:
          optionName: "OptionValue"
          compositeObject:
            name: "value"
          iAmNumber: 1

可以从交换中获取所有元数据属性:

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);

9.1。流利的Java Routes API

为了在Java中进行简单的配置,在RouteLocatorBuilderbean中定义了一个流畅的API 。

GatewaySampleApplication.java

// 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")
                .metadata("key", "value")
            )
            .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")
                .metadata("key", "value")
            )
            .build();
}

此样式还允许更多自定义谓词断言。RouteDefinitionLocatorbean 定义的谓词使用逻辑组合and。通过使用流利的Java API,你可以使用and()or()并且negate()对运营Predicate类。

9.2。DiscoveryClient路由定义定位器

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

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

9.2.1。为DiscoveryClient路由配置谓词和过滤器

默认情况下,网关为通过创建的路由定义单个谓词和过滤器DiscoveryClient

默认谓词是使用模式定义的路径谓词/serviceId/**,其中serviceId是来自的服务ID DiscoveryClient

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

如果您想自定义DiscoveryClient路线使用的谓词和/或过滤器,可以通过设置spring.cloud.gateway.discovery.locator.predicates[x]和来实现spring.cloud.gateway.discovery.locator.filters[y]。这样做时,如果要保留该功能,则需要确保在上面包含默认谓词和过滤器。以下是此示例的示例。

application.properties

spring.cloud.gateway.discovery.locator.predicates [0]。名称:路径
spring.cloud.gateway.discovery.locator.predicates [0] .args [pattern]:“'/'+ serviceId +'/ **'”
spring.cloud.gateway.discovery.locator.predicates [1]。名称:主机
spring.cloud.gateway.discovery.locator.predicates [1] .args [pattern]:“'**。foo.com'”
spring.cloud.gateway.discovery.locator.filters [0]。名称:Hystrix
spring.cloud.gateway.discovery.locator.filters [0] .args [name]:serviceId
spring.cloud.gateway.discovery.locator.filters [1]。名称:RewritePath
spring.cloud.gateway.discovery.locator.filters [1] .args [regexp]:“'/'+ serviceId +'/(?<remaining>.*)'”
spring.cloud.gateway.discovery.locator.filters [1] .args [replacement]:“'/ $ {remaining}'”

10. Reactor Netty访问日志

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

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

logback.xml

    <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>

11. CORS配置

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

application.yml

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

在上面的示例中,将从docs.spring.io发出的所有GET请求路径的请求中允许CORS请求。

要为未被某些网关路由谓词处理的请求提供相同的CORS配置,请将属性设置spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping为true。当尝试支持CORS预检请求并且您的路由谓词未评估为true时,此方法很有用,因为http方法为options

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值