首页IT科技Spring cloud gateway 限流(Spring Cloud Gateway 参考指南)

Spring cloud gateway 限流(Spring Cloud Gateway 参考指南)

时间2025-06-16 07:26:47分类IT科技浏览4631
导读:👏大家好,欢迎来到👏阿提说说👏博客 🌞“纸上得来终觉浅,绝知此事要躬行。”(南宋)陆游...

👏大家好              ,欢迎来到👏阿提说说👏博客

🌞“纸上得来终觉浅                   ,绝知此事要躬行            。              ”(南宋)陆游

🌲目前相关的教程虽然有很多      ,但总觉得被各位大佬压缩          ,看到的只是一部分知识                    ,并不全面         ,因此作者根据Spring Cloud Gateway 官方参考指南写下了这篇中文版文字教程      ,并且录制了一些视频教程                    ,希望更有助于您理解                    。

🍀Spring Cloud Gateway 版本为 3.1.3

该项目提供了一个基于Spring生态的API网关       。Spring Cloud Gateway         。Spring Cloud Gateway旨在提供一个种简单有效的方式去路由API            ,并给API提供相应关注点:如:security              、monitoring/metrics和resiliency                   。

1. 如何引入Spring Cloud Gateway

要在项目中引入Spring Cloud Gateway   ,您可以这样做:

引入Spring Cloud 统一版本依赖管理                    ,通过引入该配置               ,无需指定Spring Cloud相关组件版本 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 引入Spring Cloud Gateway配置 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>

🚩 如果引入了Spring Cloud Gateway,又不想开启                 ,可以设置spring.cloud.gateway.enabled=false

❗️ Spring Cloud Gateway建立在Spring Boot 2.x                  ,Spring WebFlux 和 Project Reactor之上   ,当您使用Spring Cloud Gateway时              ,以前的同步库(Spring Data                   、Spring Security等)并不适用           。如果您不熟悉这些项目                   ,建议您在使用Spring Cloud Gateway之前      ,先阅读他们的文档          ,熟悉一些概念      。

❗️ Spring Cloud Gateway 使用Spring Boot 和Spring Webflux 提供的Netty环境运行                    ,因此在传统的Servlet容器中不会生效                  。

2. 相关术语

Route: 路由         ,网关基础模块              。它由ID      、目标URI          、断言集合和过滤器集合组成   。如果断言为真      ,则匹配到该路由                  。 Predicate:这是一个Java8 的函数断言                 。输入类型是Spring Framework 的 ServerWebExchange。 Filter: 使用指定工厂构建的GatewayFilter的实例               。在这里                    ,您能够修改request请求和response返回在发送到下游服务之前或者之后                    。

3. 如何工作

下图是SPring Cloud Gateway的工作示意图:

客户端向Spring Cloud Gateway请求   。如果网关处理程序(Gateway Handler Mapping)确定请求与路由匹配            ,那么将其发送到网关的Web处理器(Gateway Web Handler)            。该处理程序通过过滤器链来处理请求                    。过滤器链被虚线分割的原因是   ,过滤器可以在请求发送前后运行逻辑                    ,先执行所有的“pre                   ”过滤器逻辑               ,后执行“post      ”过滤器逻辑       。

✅ 在未定义端口的URI中,HTTP默认为80                 ,HTTPS默认为443         。

4. 配置路由断言工厂和网关过滤工厂

有两种方法配置谓词和过滤器:简写和完全展开方式                   。下面的例子大都用的简写           。

4.1 简写

简写配置由过滤器名称                  ,后跟等号   ,后跟逗号分割的参数值      。

application.yml

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

4.2 完全展开

完全展开方式具有标准的name/value 对                  。一般带有name 和 args 两个key              。args用来配置断言或过滤器的键值对映射   。

application.yml

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

5. 路由断言工厂

Spring Cloud Gateway 路由匹配作为Spring WebFlux HandlerMapping 基础设施的一部分                  。Spring Cloud Gateway内置了很多路由断言工厂                 。用于匹配HTTP请求的不同属性。

5.1 After Route Predicate Factory

接收一个java ZonedDateTime的时间参数              ,表示这个时间之后的请求才能正确匹配路由               。

Example 1.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]

这个路由匹配 Jan 20, 2017 17:42 Mountain Time (Denver)之后的请求                    。

5.2 Before Route Predicate Factory

接收一个Java ZonedDateTime类的时间参数                   ,表示这个时间之前的请求才能正确匹配路由   。

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

5.3 Between Route Predicate Factory

接收两个Java ZonedDateTime类的时间参数      ,表示在第一个时间之后          ,第二个时间之前的请求才能正确匹配路由            。

Example 3. 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]

5.4 Cookie Route Predicate Factory

接收两个参数                    ,分别为name 和 regexp(Java正则表达式)         ,表示cookie中携带的name值满足正则表达式regexp      ,则被路由                    。

Example 4. application.yml

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

5.5 Header Route Predicate Factory

接收两个参数                    ,header 和 regexp(Java正则表达式)            ,表示header中携带的name值满足正则表达式regexp   ,则被路由

Example 5. application.yml

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

5.6 Host Route Predicate Factory

接收一个主机名称的集合参数                    ,用逗号分割               ,表示该断言与主机头匹配则被路由       。

Example 6. 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.org 或 beta.somehost.org 或 www.anotherhost.org都能匹配该路由                   。

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

5.7 Mehtod Route Predicate Factory

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

Example 7. application.yml

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

5.8 Path Route Predicate Factory

接收两个参数                   ,分别是Spring PathMatcher patterns 列表 和 一个matchTrailingSlash的可选标志(默认为true)                  。

Example 8. application.yml

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

如果请求地址是 /red/1 或 /red/1/ 或 /red/blue 或 /blue/green,那么路由将会被匹配              。

如果matchTrailingSlash 设置为false      ,那么/red/1/不会被匹配   。

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

可以使用一个实用方法(调用get)来简化对这些变量的访问                 。下面的例子展示了如何使用get方法:

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

5.9 Query Route Predicate Factory

接收两个参数      ,分别是一个必须的param和一个可选的regexp。

Example 9. application.yml

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

application.yml

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

如果请求中包含一个red查询参数                    ,且该参数的值匹配gree.正则表达式            ,则上述路由匹配               。所以green和greet是匹配的                    。

5.10 RemoteAddr Route Predicate Factory

接收一个sources列表(最小1个)   ,CIDR表示法(IPv4或IPv6)字符串                    ,例如192.168.0.1/16(其中192.168.0.1是一个IP地址               ,16是一个子网掩码)   。

Example 10. application.yml

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

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

5.10.1 修改远程地址的解析方式

默认情况下                 ,RemoteAddr 路由谓词工厂使用来自传入请求的远程地址                    。如果 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 前运行的受信任基础设施数量相关的索引      。例如          ,如果 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 实现相同的配置:

Example 11. GatewayConfig.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.11 Weight Route Predicate Factory

接收两个参数:分别是group 和 weight(int类型)   。权重是按组计算的                  。

Example 12. 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                 。

5.12 XForwarded Remote Addr Route Predicate Factory

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

此路由断言允许基于 X-Forwarded-For HTTP 标头过滤请求。

这可以与反向代理一起使用   ,例如负载平衡器或 Web 应用程序防火墙                    ,其中仅当请求来自这些反向代理使用的受信任的 IP 地址列表时才允许请求               。

以下示例配置 XForwardedRemoteAddr 路由谓词:

Example 13. application.yml

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

如果 X-Forwarded-For 标头包含例如 192.168.1.10               ,则此路由匹配                    。

6. 网关过滤器工厂(GatewayFilter)

路由过滤器允许修改传入的HTTP请求和传出的HTTP响应   。Spring Cloud Gateway包括了许多内置的GatewayFilter Factories            。

关于过滤器的更多示例,查看单元测试                    。

6.1 AddRequestHeader GatewayFilter Factory

接收一个name 和 value参数                 ,并将信息添加到下游的请求头中       。

Example 14. application.yml

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

AddRequestHeader支持使用URI变量来匹配path 或 host         。

Example 15. application.yml

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

6.2 AddRequestParameter GatewayFilter Factory

接收一个name 和 value 参数                  ,并添加信息到下游的请求中                   。

Example 16. application.yml

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

支持使用URI变量来匹配path 或 host           。

Example 17. 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}

6.3 AddResponseHeader GatewayFilter Factory

接收一个name 和 value 参数   ,并将信息添加到下游匹配请求的响应头中      。

Example 18. application.yml

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

支持使用URI变量来匹配path 或 host                  。

Example 19. 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}

6.4 DedupeResponseHeader GatewayFilter Factory

接收一个name参数和一个可选的strategy参数              ,name 参数根据空格分割              。

Example 20. 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

当网关CROS和下游响应头都有Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin时                   ,将删除重复的响应头   。

DedupeResponseHeader过滤器也接收可选的strategy参数      ,可接收的值是RETAIN_FIRST (default), RETAIN_LAST 和 RETAIN_UNIQUE

6.5 CircuitBreaker GatewayFilter Factory(演示)

使用 Spring Cloud CircuitBreaker的API将网关路由包装到断路器中                  。Spring Cloud CircuitBreaker 支持多种库用于Spring Cloud Gateway                 。比如Resilience4J。

要启用Spring Cloud CircuitBreaker过滤器          ,你需要引入spring-cloud-starter-circuitbreaker-reactor-resilience4j,如下是配置示例:

Example 21. application.yml

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

要配置 circuit breaker                    ,可以详细查看Resilience4J Documentation

Spring Cloud CircuitBreaker 过滤器也支持接收可选的fallbackUri参数               。当前         ,仅forward:支持      ,如果请求失败                    ,请求将会跳转到匹配URI的controller中                    。

Example 22. 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

🚩 RewritePath 表示将/consumingServiceEndpoint路径在请求前重写为/backingServiceEndpoint

下面是Java的实现方式:

Example 23. Application.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")) .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088") .build(); }

当前请求被熔断时            ,将被回调到/inCaseofFailureUseThis   。

✅ 动图演示

gateway: 测试网关

backing-service: 测试后端服务

熔断跳转到inCaseOfFailureUseThis

重写跳转到backingServiceEndpoint

这里fallbackUri主要使用在网关应用程序内部定义controller或者handler            。您也可以重路由到外部应用程序                    。如下示例:

Example 24. 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的应用程序         。

在请求被转发到fallback的时候                    ,Spring Cloud CircuitBreaker Gateway filter 也提供Throwable异常                   。它被添加到ServerWebExchange 的ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR中               ,以便可以在网关应用程序中使用           。

对于外部controller/handler场景,可以添加带有异常详情信息的头      。您可以在FallbackHeaders GatewayFilter Factory section中找到更多详情                  。

6.5.1 根据状态码熔断

通过配置的statusCodes                 ,当返回配置的状态码时                  ,请求熔断              。状态码可以配置整型状态码值或者HttpStatus的枚举字符串   。

Example 25. 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 statusCodes: - 500 - "NOT_FOUND"

Java 代码表示

Example 26. Application.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.6 FallbackHeaders GatewayFilter Factory

FallbackHeaders 工厂允许您在转发到外部应用程序的fallbackUri中添加Spring Cloud CircuitBreaker 详细的异常信息   ,如下所示:

Example 27. 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

在该例中              ,在运行circuit breaker 发生异常后                   ,请求将被转发到http://localhost:9994的/fallback中                  。异常类型                    、消息等通过FallbackHeaders过滤器添加到请求头中                 。

通过设置下面列出的参数值      ,可以在配置中覆盖headers的名称。

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

更多详情查看Spring Cloud CircuitBreaker Factory section

6.7 MapRequestHeader GatewayFilter Factory(演示)

接收两个参数          ,分别是fromHeader 和 toHeader               。它会创建一个新的header(toHeader),并从fromHeader中提取值                    。如果输入的header不存在                    ,该过滤器不会执行   。如果新的header已经存在         ,那么它将被追加新值            。如下所示:

Example 28. application.yml

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

该示例会将X-Request-Red:<values>头添加到下游请求中      ,值为传入的HTTP请求Blue值                    。

✅视频演示

6.8 PrefixPath GatewayFilter Factory

接收一个参数prefix

Example 29. application.yml

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

该示例将在所有匹配请求路径前加上前缀/mypath                    ,因此请求/hello时            ,将发送到/mypath/hello中       。

6.9 PreserveHostHeader GatewayFilter Factory(演示)

该过滤工厂没有接收参数         。设置了该Filter后   ,GatewayFilter将不使用由HTTP客户端确定的host header                     ,而是发送原始host header                   。

Example 30. application.yml

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

✅视频演示

PreserveHostHeader GatewayFilter 示例演示

6.10 RequestRateLimiter GatewayFilter Factory

该过滤器使用RateLimiter来实现是否允许继续执行该请求           。如果不允许继续执行               ,返回HTTP 429 - Too Many Requests(默认情况下)      。

该过滤器可以配置一个可选的keyResolver 参数和rate limiter参数                  。

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

Example 31. KeyResolver.java

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

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

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

默认情况下              ,如果KeyResolver 没有获取到key                   ,请求将被拒绝               。您可以通过如下设置来调整:

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 不能使用“shortcut                    ”来配置      ,如下配置无效:

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

6.10.1 Redis RateLimiter(演示)

Redis实现基于Stripe                    。它需要引入spring-boot-starter-data-redis-reactive依赖   。

使用的算法是Token Bucket Algorithm            。

redis-rate-limiter.replenishRate配置是在不丢弃任何请求的情况下          ,你允许用户每秒执行多少请求                    。这是令牌桶的填充速率       。

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

redis-rate-limiter.requestedTokens配置一个请求所需要的令牌数      。每个请求从令牌桶提取的令牌数                    ,默认为1                  。

通过在replenishRate 和 burstCapacity中设置相同的值来实现稳定的速率              。可通过设置burstCapacity高于replenishRate来允许临时突发流量   。在这种情况下         ,限流器需要在两次突发之间留出一段时间(根据replenishRate)      ,因为连续两次突发将导致请求丢失 (HTTP 429 - Too Many Requests)                  。如下列表配置了一个redis-rate-limiter:

比如:replenishRate=1         、requestedTokens=60 和 burstCapacity=60将限制为 1 request/min                 。

Example 33. 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 redis-rate-limiter.requestedTokens: 1

配置一个KeyResolver

**Example 34. Config.java

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

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

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

Example 35. application.yml

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

✅视频演示

RetryGatewayFilter 示例教程演示

6.11 RedirectTo GatewayFilter Factory

接收两个参数:status和url       。

status是300类重定向HTTP码   ,如301         。该url应该是一个有效的URL                    ,值是Location header的值                   。

对于相对路径               ,应该使用uri: no://op作为路由定义           。

Example 36. application.yml

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

该例将发送一个302重定向状态码到Location:https://acme.org      。

6.12 RemoveRequestHeader GatewayFilter Factory

接收一个name参数,该值是将要被删除header的name                  。

Example 37. application.yml

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

该例表示将从header中删除X-Request-Foo              。

6.13 RemoveResponseHeader GatewayFilter Factory

接收一个参数name                 ,name将在响应返回之前被删除   。

Example 38. application.yml

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

该例表示响应在返回网关之前将从header中删除X-Response-Foo                  。

可以使用spring.cloud.gateway.default-filters配置默认过滤                  ,该默认过滤对所有路由有效                 。

6.14 RemoveRequestParameter GatewayFilter Factory

接收一个name参数   ,它是要被删除请求参数的name值。

Example 39. application.yml

spring: cloud: gateway: routes: - id: removerequestparameter_route uri: https://example.org filters: - RemoveRequestParameter=red

该例表示在将请求发送到下游之前              ,删除red参数               。

6.15 RequestHeaderSize GatewayFilter Factory

接收两个参数                   ,maxSize 和 errorHeaderName                    。

maxSize表示请求头的最大数据带下(包括key和value)   。errorHeaderName用于设置响应头的名称      ,包含错误信息          ,默认名称为errorMessage            。

Example 40. application.yml

spring: cloud: gateway: routes: - id: requestheadersize_route uri: https://example.org filters: - RequestHeaderSize=1000B

该示例表示如果请求超过了1000Bytes                    ,将发送一个431的状态码                    。

6.16 RewritePath GatewayFilter Factory

接收一个regexp和replacement参数       。使用了Java正则表达式来重写请求地址         。

Example 41. application.yml

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

对于/red/blue请求路径         ,将在发送到下游之前替换为/blue                   。因为YAML规范      ,要把$替换为$\           。

6.17 RewriteLocationResponseHeader GatewayFilter Factory

该过滤器修改Location响应头的值                    ,经常用于去掉一些敏感信息      。接收参数分别是:

stripVersionMode, locationHeaderName, hostValue, protocolsRegex                  。

Example 42. application.yml

spring: cloud: gateway: routes: - id: rewritelocationresponseheader_route uri: http://example.org filters: - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

示例表示            ,一个POST请求 api.example.com/some/object/name,Location响应头的值是object-service.prod.example.net/v2/some/object/id将被重写为api.example.com/some/object/id              。

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

NEVER_STRIP:原始的请求中不包含版本   ,也不会去掉版本

AS_IN_REQUEST:原始请求中不包含版本                    ,响应头就去掉版本

ALWAYS_STRIP:始终会去掉版本

hostValue参数:如果提供该值               ,将用于替换host:port响应Location头的值,如果为空                 ,则使用请求中名为Host的header值                  。

protocolsRegex 参数是一个有效的正则字符串                 。如果不匹配                  ,则过滤器不执行。默认值为http | https | ftp | ftps               。

6.18 RewriteResponseHeader GatewayFilter Factory

接收name      、regexp                    、replacement三个参数                    。使用Java正则表达式重写响应header头   。

Example 43. application.yml

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

在下游响应返回到网关后   ,该示例将把/42?user=ford&password=omg!what&flag=true头的值              ,设置为/42?user=ford&password=***&flag=true            。您必须使用$\代替$                    。

6.19 SaveSession GatewayFilter Factory

SaveSession GatewayFilter Factory将调用转发到下游之前强制执行WebSession::save 操作       。这在使用 Spring Session 之类时特别有用                   ,需要确保会话状态在进行转发调用之前已保存         。

Example 44. application.yml

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

如果你希望要将Spring Security与Spring Session集成,并要确保安全信息都传到下游      ,这样做将是很重要的                   。

6.20 SecureHeaders GatewayFilter Factory

根据这篇blog的建议          ,SecureHeaders GatewayFilter Factory在response响应中添加了许多头           。

添加了以下的头(默认值):

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禁用默认值                    ,全小写逗号分割

6.21 SetPath GatewayFilter Factory

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

Example 45. application.yml

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

如上所示:请求/red/blue,将在请求下游时将路径设置为/blue

6.22 SetRequestHeader GatewayFilter Factory

采用name和value参数   。

Example 46. application.yml

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

该GatewayFilter将会使用给定的name替换所有的header                    ,而不是添加                  。因此会将请求头从X-Request-Red:1234设置为X-Request-Red:Blue                 。

SetRequestHeader 允许使用path或者host的URI变量。

Example 47. application.yml

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

6.23 SetResponseHeader GatewayFilter Factory

两个参数name和value               。

Example 48. application.yml

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

该GatewayFilter将会使用给定的name替换所有的header            ,而不是添加                    。下游响应的头X-Response-Red:1234将会替换成X-Response-Red:Blue   。

SetResponseHeader 也使用path或者host的URI变量            。

Example 49. application.yml

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

6.24 SetStatus GatewayFilter Factory(演示)

接收一个参数status   ,必须是一个可用的Spring HttpStatus值                    ,可用是整数或者枚举字符串                    。

Example 50. application.yml

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

该示例               ,将HTTP status响应头设置为401       。

使用SetStatus 可以在响应中返回代理请求中的原始Http 状态码         。如下配置,将header添加到响应中                   。

Example 51. application.yml

spring: cloud: gateway: set-status: original-status-header-name: original-http-status

✅演示

如下示例配置了original-status-header-name: original-http-status和SetStatus=401                 ,效果如下:

6.25 StripPrefix GatewayFilter Factory

接收一个parts参数           。 parts参数指示在将请求发送到下游之前                  ,要从请求中去除的路径中的节数      。

Example 52. application.yml

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

该示例表示当网关发送/name/blue/red请求时   ,实际向下游请求的地址是nameservice/red                  。

6.26 Retry GatewayFilter Factory(演示)

Retry GatewayFilter Factory使用了reactor-addons 的retry组件进行重试              ,支持以下参数:

retries:应尝试的重试次数 statuses:应尝试的HTTP状态码 methods:应尝试的HTTP方法 series:应尝试的series状态码                   ,org.springframework.http.HttpStatus.Series exceptions:应尝试的异常列表 backoff:配置指数退避重试              。根据firstBackoff * (factor ^ n)进行指数重试      ,maxBackoff 限制最大退避重试          ,如果basedOnPreviousValue 为true                    ,则退避指数计算使用prevBackoff * factor   。

Retry 过滤器默认值配置如下:

retries: 3次 series: 5XX series methods:GET 方法 exceptions:IOException 和 TimeoutException backoff: disabled

Example 53. application.yml

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

❗️ 当重试过滤器与任何带body的HTTP请求使用时         ,body会被缓存                  。body被缓存在请求定义的的ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR中      ,对象类型是:org.springframework.core.io.buffer.DataBuffer                 。

使用单个status和method                    ,可以使用简便的方式添加:

Example 54. application.yml 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

✅演示

RetryGatewayFilter 示例教程演示

6.27 RequestSize GatewayFilter Factory

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

Example 55. application.yml

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               ,并带有额外的header errorMessage                     。

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

❗️ 如果未在路由定义中作为filter参数提供,则默认请求大小将设置为5 MB

6.28 SetRequestHostHeader GatewayFilter Factory

接收一个host参数                 ,用于覆盖主机头   。

Example 56. application.yml

spring: cloud: gateway: routes: - id: set_request_host_header_route uri: http://localhost:8080/headers predicates: - Path=/headers filters: - name: SetRequestHostHeader args: host: example.org

该示例表示使用example.org代替host头的值            。

6.29 ModifyRequestBodyGatewayFilterFactory

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

❗️ 只能使用Java DSL配置此过滤器       。如果没有body                  ,RewriteFilter 会传递null         。

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

6.30 Modify Response Body GatewayFilter Factory

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

❗️ 只能使用Java DSL配置此过滤器           。如果没有body   ,RewriteFilter 会传递null      。

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

6.31 Token Relay GatewayFilter Factory

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

Spring Cloud Gateway 可以将OAuth2访问令牌转发到其代理的服务下游   。要将此功能添加到网关              ,您需要添加TokenRelayGatewayFilterFactory                   。

App.java

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

或者

application.yaml

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

工作原理:TokenRelayGatewayFilterFactory会从认证的用户中提取access token                   ,并放入发送给下游的请求中。示例见:thi project.

❗️ ReactiveOAuth2AuthorizedClientService的默认实现是TokenRelayGatewayFilterFactory      ,使用内存存储          ,如果需要自定义                    ,需要自己实现ReactiveOAuth2AuthorizedClientService                。

6.32 CacheRequestBody GatewayFilter Factory

由于请求body流只能读取一次         ,因此我们需要缓存请求的body                    。可以使用CacheRequestBody 缓存body      ,并从exchange 中获取该body   。

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

Example 57. application.yml

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并转换成body 指定的类            。(本例中是java.lang.String)                    。缓存中定义的key为ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR       。

❗️ 仅支持http/https 请求

6.33 Default Filters

可以使用spring.cloud.gateway.default-filters作为所有路由的过滤器         。该配置接收一个filter列表                    ,如下:

Example 58. application.yml

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

7. Global Filters

GlobalFilter接口与GatewayFilter具有相同的签名                   。是有条件地应用于所有路由的特殊过滤器           。

❗️ 此接口和用法可能在将来的里程碑版本中发生更改

7.1 全局Filter和GatewayFilter组合排序

当请求匹配到路由时            ,web 过滤处理器会将所有的 GlobalFilter 实例和指定的GatewayFilter实例添加到过滤器链      。filter的排序由org.springframework.core.Ordered接口决定   ,可以通过getOrder()方法或者@Order注释来设置                  。

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

如下配置了一个过滤器链:

Example 59. ExampleConfiguration.java

@Bean public GlobalFilter customFilter() { return new 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; } }

7.2 Forward Routing Filter

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
提高网站搜索排名的方法(提高网站知名度的方法) 域名是企业的网络商标(“网络域名与商标——保护你的品牌”)