gateway网关的一般常用配置说明

傻男人 1年前 ⋅ 640 阅读

gateway网关的一般常用配置说明

路由网关的配置

一、开启服务id去注册中心获取转发的地址

spring:
  cloud:
      gateway:
        # 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
        discovery:
          locator:
            ####开启以服务id去注册中心上获取转发地址
            enabled: true

二、routes中的predicates 断言 匹配规则说明

Spring Cloud Gateway是使用Spring WebFlux的HandlerMapping作为匹配路由底层实现,本身已自带很多Route Predicate Factories, 分别匹配不同的http请求属性,多个Route Predicate Factories也可以通过and进行逻辑合并匹配。

1. After Route Predicate Factory

After Route Predicate Factory使用的是时间作为匹配规则,只要当前时间大于设定时间,路由才会匹配请求。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: http://www.google.com
        predicates:
        - After=2018-12-25T14:33:47.789+08:00

这个路由规则会在东8区的2018-12-25 14:33:47后,将请求都转跳到google。

2. Before Route Predicate Factory

Before Route Predicate Factory也是使用时间作为匹配规则,只要当前时间小于设定时间,路由才会匹配请求。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: http://www.google.com
        predicates:
        - Before=2018-12-25T14:33:47.789+08:00

这个路由规则会在东8区的2018-12-25 14:33:47前,将请求都转跳到google。

3. Between Route Predicate Factory

Between Route Predicate Factory也是使用两个时间作为匹配规则,只要当前时间大于第一个设定时间,并小于第二个设定时间,路由才会匹配请求。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: http://www.google.com
        predicates:
        - Between=2018-12-25T14:33:47.789+08:00, 2018-12-26T14:33:47.789+08:00

这个路由规则会在东8区的2018-12-25 14:33:47到2018-12-26 14:33:47之间,将请求都转跳到google。

4. Cookie Route Predicate Factory

Cookie Route Predicate Factory使用的是cookie名字和正则表达式的value作为两个输入参数,请求的cookie需要匹配cookie名和符合其中value的正则。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: http://www.google.com
        predicates:
        - Cookie=cookiename, cookievalue

路由匹配请求存在cookie名为cookiename,cookie内容匹配cookievalue的,将请求转发到google。

5. Header Route Predicate Factory

Header Route Predicate Factory,与Cookie Route Predicate Factory类似,也是两个参数,一个header的name,一个是正则匹配的value。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: http://www.google.com
        predicates:
        - Header=X-Request-Id, \d+

路由匹配存在名为X-Request-Id,内容为数字的header的请求,将请求转发到google。

6. Host Route Predicate Factory

Host Route Predicate Factory使用的是host的列表作为参数,host使用Ant style匹配。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://www.google.com
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

路由会匹配Host诸如:www.somehost.org 或 beta.somehost.org或www.anotherhost.org等请求。

7. Method Route Predicate Factory

Method Route Predicate Factory是通过HTTP的method来匹配路由。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://www.google.com
        predicates:
        - Method=GET

路由会匹配到所有GET方法的请求。

8. Path Route Predicate Factory

Path Route Predicate Factory使用的是path列表作为参数,使用Spring的PathMatcher匹配path,可以设置可选变量。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://www.google.com
        predicates:
        - Path=/foo/{segment},/bar/{segment}

上面路由可以匹配诸如:/foo/1 或 /foo/bar 或 /bar/baz等 其中的segment变量可以通过下面方式获取:

PathMatchInfo variables = exchange.getAttribute(URI_TEMPLATE_VARIABLES_ATTRIBUTE);
Map<String, String> uriVariables = variables.getUriVariables();
String segment = uriVariables.get("segment");

在后续的GatewayFilter Factories就可以做对应的操作了。

9. Query Route Predicate Factory

Query Route Predicate Factory可以通过一个或两个参数来匹配路由,一个是查询的name,一个是查询的正则value。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://www.google.com
        predicates:
        - Query=baz

路由会匹配所有包含baz查询参数的请求。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://www.google.com
        predicates:
        - Query=foo, ba.

路由会匹配所有包含baz,并且baz的内容为诸如:bar或baz等符合ba.正则规则的请求。

10. RemoteAddr Route Predicate Factory

RemoteAddr Route Predicate Factory通过无类别域间路由(IPv4 or IPv6)列表匹配路由。 application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://www.google.com
        predicates:
        - RemoteAddr=192.168.1.1/24

上面路由就会匹配RemoteAddr诸如192.168.1.10等请求。

10.1 Modifying the way remote addresses are resolved

RemoteAddr Route Predicate Factory默认情况下,使用的是请求的remote address。但是如果Spring Cloud Gateway是部署在其他的代理后面的,如Nginx,则Spring Cloud Gateway获取请求的remote address是其他代理的ip,而不是真实客户端的ip。

考虑到这种情况,你可以自定义获取remote address的处理器RemoteAddressResolver。当然Spring Cloud Gateway也提供了基于X-Forwarded-For请求头的XForwardedRemoteAddressResolver。 熟悉Http代理协议的,都知道X-Forwarded-For头信息做什么的,不熟悉的可以自己谷歌了解一下。

XForwardedRemoteAddressResolver提供了两个静态方法获取它的实例: XForwardedRemoteAddressResolver::trustAll得到的RemoteAddressResolver总是获取X-Forwarded-For的第一个ip地址作为remote address,这种方式就比较容易被伪装的请求欺骗,模拟请求很容易通过设置初始的X-Forwarded-For头信息,就可以欺骗到gateway。

XForwardedRemoteAddressResolver::maxTrustedIndex得到的RemoteAddressResolver则会在X-Forwarded-For信息里面,从右到左选择信任最多maxTrustedIndex个ip,因为X-Forwarded-For是越往右是越接近gateway的代理机器ip,所以是越往右的ip,信任度是越高的。 那么如果前面只是挡了一层Nginx的话,如果只需要Nginx前面客户端的ip,则maxTrustedIndex取1,就可以比较安全地获取真实客户端ip。

使用java的配置: GatewayConfig.java:

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("http://www.google.com")
.route("proxied-route",
    r -> r.remoteAddr(resolver,  "10.10.1.1", "10.10.1.1/24")
        .uri("http://www.google.com")
)

三、routes中的filters 匹配规则说明

GatewayFilter Factories Route filters可以通过一些方式修改HTTP请求的输入和输出,针对某些特殊的场景,Spring Cloud Gateway已经内置了很多不同功能的GatewayFilter Factories。

下面就来通过例子逐一讲解这些GatewayFilter Factories。

1. AddRequestHeader GatewayFilter Factory

AddRequestHeader GatewayFilter Factory通过配置name和value可以增加请求的header。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://www.google.com
        filters:
        - AddRequestHeader=X-Request-Foo, Bar

对匹配的请求,会额外添加X-Request-Foo:Bar的header。

2. AddRequestParameter GatewayFilter Factory

AddRequestParameter GatewayFilter Factory通过配置name和value可以增加请求的参数。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: http://www.google.com
        filters:
        - AddRequestParameter=foo, bar

对匹配的请求,会额外添加foo=bar的请求参数。

3. AddResponseHeader GatewayFilter Factory

AddResponseHeader GatewayFilter Factory通过配置name和value可以增加响应的header。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://www.google.com
        filters:
        - AddResponseHeader=X-Response-Foo, Bar

对匹配的请求,响应返回时会额外添加X-Response-Foo:Bar的header返回。

  1. Hystrix GatewayFilter Factory Hystrix是Netflix实现的断路器模式工具包,The Hystrix GatewayFilter就是将断路器使用在gateway的路由上,目的是保护你的服务避免级联故障,以及在下游失败时可以降级返回。

项目里面引入spring-cloud-starter-netflix-hystrix依赖,并提供HystrixCommand的名字,即可生效Hystrix GatewayFilter。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: http://www.google.com
        filters:
        - Hystrix=myCommandName

那么剩下的过滤器,就会包装在名为myCommandName的HystrixCommand中运行。

Hystrix过滤器也是通过配置可以参数fallbackUri,来支持路由熔断后的降级处理,降级后,请求会跳过fallbackUri配置的路径,目前只支持forward:的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

当Hystrix降级后就会将请求转发到/incaseoffailureusethis。

整个流程其实是用fallbackUri将请求跳转到gateway内部的controller或者handler,然而也可以通过以下的方式将请求转发到外部的服务:

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

以上的例子,gateway降级后就会将请求转发到http://localhost:9994。

Hystrix Gateway filter在转发降级请求时,会将造成降级的异常设置在ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR属性中,在处理降级时也可以用到。

比如下一节讲到的FallbackHeaders GatewayFilter Factory,就会通过上面的方式拿到异常信息,设置到降级转发请求的header上,来告知降级下游异常信息。

通过下面配置可以设置Hystrix的全局超时信息:

application.yml:

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
5. FallbackHeaders GatewayFilter Factory

FallbackHeaders GatewayFilter Factory可以将Hystrix执行的异常信息添加到外部请求的fallbackUriheader上。

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
        filters:
        - name: FallbackHeaders
          args:
            executionExceptionTypeHeaderName: Test-Header

在这个例子中,当请求lb://ingredients降级后,FallbackHeadersfilter会将HystrixCommand的异常信息,通过Test-Header带给http://localhost:9994服务。

你也可以使用默认的header,也可以像上面一下配置修改header的名字:

executionExceptionTypeHeaderName ("Execution-Exception-Type")
executionExceptionMessageHeaderName ("Execution-Exception-Message")
rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
6. PrefixPath GatewayFilter Factory

The PrefixPath GatewayFilter Factor通过设置prefix参数来路径前缀。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://www.google.com
        filters:
        - PrefixPath=/mypath

如果一个请求是/hello,通过上面路由,就会将请求修改为/mypath/hello。

7. PreserveHostHeader GatewayFilter Factory

PreserveHostHeader GatewayFilter Factory会保留原始请求的host头信息,并原封不动的转发出去,而不是被gateway的http客户端重置。

application.yml:

spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: http://www.google.com
        filters:
        - PreserveHostHeader
8. RequestRateLimiter GatewayFilter Factory

RequestRateLimiter GatewayFilter Factory使用RateLimiter来决定当前请求是否允许通过,如果不允许,则默认返回状态码HTTP 429 - Too Many Requests。

RequestRateLimiter GatewayFilter可以使用一个可选参数keyResolver来做速率限制。

keyResolver是KeyResolver接口的一个实现bean,在配置里面,通过SpEL表达式#{@myKeyResolver}来管理bean的名字myKeyResolver。

KeyResolver.java.

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

KeyResolver接口允许你使用不同的策略来得出限制请求的key,未来,官方也会推出一些KeyResolver的不同实现。

KeyResolver默认实现是PrincipalNameKeyResolver,通过ServerWebExchange中获取Principal,并以Principal.getName()作为限流的key。

如果KeyResolver拿不到key,请求默认都会被限制,你也可以自己配置

spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key:是否允许空key,
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code :空key时返回的状态码。

RequestRateLimiter不支持捷径配置,如下面的配置是非法的

application.properties.

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

基于 Stripe的redis实现方案,依赖spring-boot-starter-data-redis-reactiveSpring Boot starter,使用的是令牌桶算法。

redis-rate-limiter.replenishRate配置的是每秒允许通过的请求数,其实就是令牌桶的填充速率。

redis-rate-limiter.burstCapacity配置的是一秒内最大的请求数,其实就是令牌桶的最大容量,如果设置为0,则会阻塞所有请求。

所以可以通过设置相同的replenishRate和burstCapacity来实现匀速的速率控制,通过设置burstCapacity大于replenishRate来允许系统流量瞬间突发,但是对于这种情况,突发周期为burstCapacity / replenishRate秒,如果周期内有两次请求突发的情况,则第二次会有部分请求丢失,返回HTTP 429 - Too Many Requests。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://www.google.com
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20

Config.java.

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

上面定义了每个用户每秒10个请求的速率限制,允许20的突发流量,突发完,下一秒只允许10个请求通过了,KeyResolver定义了通过请求获取请求参数user作为key。

你也可以实现RateLimiter接口自定义自己的请求速率限制器,在配置文件中使用SpEL表达式配置对应的bean的名字即可。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://www.google.com
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@myRateLimiter}"
            key-resolver: "#{@userKeyResolver}"
9. RedirectTo GatewayFilter Factory

RedirectTo GatewayFilter Factory使用status和url两个参数,其中status必须是300系列的HTTP状态码,url则是跳转的地址,会放在响应的Location的header中(http协议中转跳的header)。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://www.google.cn
        filters:
        - RedirectTo=302, http://www.edjdhbb.com

上面路由会执行302重定向到http://www.edjdhbb.com。

10. RemoveNonProxyHeaders GatewayFilter Factory

RemoveNonProxyHeaders GatewayFilter Factory转发请求是会根据IETF的定义,默认会移除下列的http头信息:

Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
TE
Trailer
Transfer-Encoding
Upgrade

你也可以通过配置

spring.cloud.gateway.filter.remove-non-proxy-headers.headers

来更改需要移除的header列表。

11. RemoveRequestHeader GatewayFilter Factory

RemoveRequestHeader GatewayFilter Factory配置header的name,即可以移除请求的header。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: http://www.google.com
        filters:
        - RemoveRequestHeader=X-Request-Foo

上面路由在发送请求给下游时,会将请求中的X-Request-Foo头信息去掉。

12. RemoveResponseHeader GatewayFilter Factory

RemoveResponseHeader GatewayFilter Factory通过配置header的name,会在响应返回时移除header。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: http://www.google.com
        filters:
        - RemoveResponseHeader=X-Response-Foo

上面路由会在响应返回给gateway的客户端时,将X-Response-Foo响应头信息去掉。

13. RewritePath GatewayFilter Factory

RewritePath GatewayFilter Factory使用路径regexp和替换路径replacement两个参数做路径重写,两个都可以灵活地使用java的正则表达式。

application.yml.

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

对于上面的例子,如果请求的路径是/foo/bar,则gateway会将请求路径改为/bar发送给下游。

注:在YAML 的格式中使用$\来代替$。

14. RewriteResponseHeader GatewayFilter Factory

RewriteResponseHeader GatewayFilter Factory的作用是修改响应返回的header内容,需要配置响应返回的header的name,匹配规则regexp和替换词replacement,也是支持java的正则表达式。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: rewriteresponseheader_route
        uri: http://www.google.com
        filters:
        - RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***

举个例子,对于上面的filter,如果响应的headerX-Response-Foo的内容是/42?user=ford&password=omg!what&flag=true,这个内容会修改为/42?user=ford&password=***&flag=true。

15. SaveSession GatewayFilter Factory

SaveSession GatewayFilter Factory会在请求下游时强制执行WebSession::save方法,用在那种像Spring Session延迟数据存储的,并在请求转发前确保session状态保存情况。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: http://www.google.com
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

如果你将Spring Secutiry于Spring Session集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。

16. SecureHeaders GatewayFilter Factory

SecureHeaders GatewayFilter Factory会添加在返回响应中一系列安全作用的header,至于为什么,英文好的可以看一下这篇博客。

默认会添加这些头信息和默认内容:

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

上面的header对应的后缀: 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.xss-protection-header
17. SetPath GatewayFilter Factory

SetPath GatewayFilter Factory采用路径template参数,通过请求路径的片段的模板化,来达到操作修改路径的母的,运行多个路径片段模板化。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: http://www.google.com
        predicates:
        - Path=/foo/{segment}
        filters:
        - SetPath=/{segment}

对于上面的例子,如果路径是/foo/bar,则对于下游的请求路径会修改为/bar。

18. SetResponseHeader GatewayFilter Factory

SetResponseHeader GatewayFilter Factory通过设置name和value来替换响应对于的header。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: http://www.google.com
        filters:
        - SetResponseHeader=X-Response-Foo, Bar

对于上面的例子,如果下游的返回带有头信息为X-Response-Foo:1234,则会gateway会替换为X-Response-Foo:Bar,在返回给客户端。

19. SetStatus GatewayFilter Factory

SetStatus GatewayFilter Factory通过配置有效的Spring HttpStatus枚举参数,可以是类似于404的这些数字,也可以是枚举的name字符串,来修改响应的返回码。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: http://www.google.com
        filters:
        - SetStatus=BAD_REQUEST
      - id: setstatusint_route
        uri: http://www.google.com
        filters:
        - SetStatus=401

上面例子中,两种路由都会将响应的状态码设置为401。

20. StripPrefix GatewayFilter Factory

StripPrefix GatewayFilter Factory通过配置parts来表示截断路径前缀的数量。

application.yml.

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

如上面例子中,如果请求的路径为/name/bar/foo,则路径会修改为/foo,即将路径的两个前缀去掉了。

21. Retry GatewayFilter Factory

Retry GatewayFilter Factory可以配置针对不同的响应做请求重试,可以配置如下参数:

retries: 重试次数 statuses: 需要重试的状态码,需要根据枚举 org.springframework.http.HttpStatus来配置 methods: 需要重试的请求方法,需要根据枚举org.springframework.http.HttpMethod来配置 series: HTTP状态码系列,详情见枚举org.springframework.http.HttpStatus.Series 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

上面例子,当下游服务返回502状态码时,gateway会重试3次。

22. RequestSize GatewayFilter Factory

RequestSize GatewayFilter Factory会限制客户端请求包的大小,通过参数RequestSize来配置最大上传大小,单位字节。

application.yml.

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

如果请求大小超过5000kb限制,则会返回状态码413 Payload Too Large。

如果不设置这个filter,默认限制5M的请求大小。

23. Modify Request Body GatewayFilter Factory

官方说这个filter目前只是beta版本,API以后可能会修改。

Modify Request Body GatewayFilter Factory可以修改请求体内容,这个只能通过java来配置。

@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;
    }
}
24. Modify Response Body GatewayFilter Factory

官方说这个filter目前只是beta版本,API以后可能会修改。

Modify Response Body GatewayFilter Factory用于修改响应返回的内容,同样只能通过java配置。

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

四、Global Filters 全局过滤器

GlobalFilter接口方法和GatewayFilter是一样的,GlobalFilter特别之处在于它的作用是全局的。

1. Combined Global Filter and GatewayFilter Ordering

当请求到来时,Filtering Web Handler处理器会添加所有GlobalFilter实例和匹配的GatewayFilter实例到过滤器链中,通过对filterbean配置注解@Order,则过滤器链会对这些过滤器实例bean进行排序。

Spring Cloud Gateway将过滤器的逻辑按请求执行点分为”pre”和”post”的一前一后处理,如果是高优先级的过滤器,则在”pre”逻辑中最先执行,在”post”逻辑中最后执行。

ExampleConfiguration.java.

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

上面例子陆续会打印的是:

first pre filter
second pre filter
third pre filter
first post filter
second post filter
third post filter
2. Forward Routing Filter

ForwardRoutingFilter会查看exchange的属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的URI内容,如果url的scheme是forward,比如:forward://localendpoint,则它会使用Spirng的DispatcherHandler来处理这个请求。

源码实现:

@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);

		String scheme = requestUrl.getScheme();
		if (isAlreadyRouted(exchange) || !"forward".equals(scheme)) {
			return chain.filter(exchange);
		}
		setAlreadyRouted(exchange);

		//TODO: translate url?

		if (log.isTraceEnabled()) {
			log.trace("Forwarding to URI: "+requestUrl);
		}

		return this.dispatcherHandler.handle(exchange);
	}
3. LoadBalancerClient Filter

LoadBalancerClientFilter会查看exchange的属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的URI内容,如果url的scheme是lb,比如:lb://myservice,或者是ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性的内容是lb,则它会使用Spring Cloud的LoadBalancerClient来将host转化为实际的host和port,并以此替换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的内容,原来的URL则会被添加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性的列表中。

源码实现:

@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
		String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
		if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
			return chain.filter(exchange);
		}
		//preserve the original url
		addOriginalRequestUrl(exchange, url);

		log.trace("LoadBalancerClientFilter url before: " + url);

		final ServiceInstance instance = loadBalancer.choose(url.getHost());

		if (instance == null) {
			throw new NotFoundException("Unable to find instance for " + url.getHost());
		}

		URI uri = exchange.getRequest().getURI();

		// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
		// if the loadbalancer doesn't provide one.
		String overrideScheme = null;
		if (schemePrefix != null) {
			overrideScheme = url.getScheme();
		}

		URI requestUrl = loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);

		log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
		exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
		return chain.filter(exchange);
	}

application.yml.

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

默认情况下,如果LoadBalancer找不到服务实例,则会返回HTTP状态码503,你也可以通过修改spring.cloud.gateway.loadbalancer.use404=true配置修改为返回状态码404。

4. Netty Routing Filter

如果ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR属性中的url的scheme是http或https,则Netty Routing Filter才会执行,并使用Netty作为http请求客户端对下游进行代理请求。请求的响应会放在exchange的ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR属性中,以便后面的filter做进一步的处理。

5. Netty Write Response Filter

如果NettyWriteResponseFilter发现exchange的ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR属性中存在Netty的HttpClientResponse类型实例,在所有过滤器都执行完毕后,它会将响应写回到gateway客户端的响应中。

源码实现:

@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
		// until the WebHandler is run
		return chain.filter(exchange).then(Mono.defer(() -> {
			HttpClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);

			if (clientResponse == null) {
				return Mono.empty();
			}
			log.trace("NettyWriteResponseFilter start");
			ServerHttpResponse response = exchange.getResponse();

			NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory();
			//TODO: what if it's not netty

			final Flux<NettyDataBuffer> body = clientResponse.receive()
					.retain() //TODO: needed?
					.map(factory::wrap);

			MediaType contentType = response.getHeaders().getContentType();
			return (isStreamingMediaType(contentType) ?
					response.writeAndFlushWith(body.map(Flux::just)) : response.writeWith(body));
		}));
	}

	//TODO: use framework if possible
	//TODO: port to WebClientWriteResponseFilter
	private boolean isStreamingMediaType(@Nullable MediaType contentType) {
		return (contentType != null && this.streamingMediaTypes.stream()
						.anyMatch(contentType::isCompatibleWith));
	}
6. RouteToRequestUrl Filter

如果exchange的ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR属性存放了Route对象,则RouteToRequestUrlFilter会根据基于请求的URI创建新的URI,新的URI会更新到ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR属性中。

如果URI有scheme前缀,比如:lb:ws://serviceid,lbscheme截取出来放到ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性中,方便后面的filter使用。

源码实现:

@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
		if (route == null) {
			return chain.filter(exchange);
		}
		log.trace("RouteToRequestUrlFilter start");
		URI uri = exchange.getRequest().getURI();
		boolean encoded = containsEncodedParts(uri);
		URI routeUri = route.getUri();

		if (hasAnotherScheme(routeUri)) {
			// this is a special url, save scheme to special attribute
			// replace routeUri with schemeSpecificPart
			exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, routeUri.getScheme());
			routeUri = URI.create(routeUri.getSchemeSpecificPart());
		}

		URI requestUrl = UriComponentsBuilder.fromUri(uri)
				.uri(routeUri)
				.build(encoded)
				.toUri();
		exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
		return chain.filter(exchange);
	}

	/* for testing */ static boolean hasAnotherScheme(URI uri) {
		return schemePattern.matcher(uri.getSchemeSpecificPart()).matches() && uri.getHost() == null
				&& uri.getRawPath() == null;
	}
7. Websocket Routing Filter

如果请求URL的scheme是ws或wss的话,那么Websocket Routing Filter就会使用Spring Web Socket底层来处理对下游的请求转发。

如果Websocket也使用了负载均衡,则需要这样配置:lb:ws://serviceid.

源码实现:

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    changeSchemeIfIsWebSocketUpgrade(exchange);

    URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
    String scheme = requestUrl.getScheme();

    if (isAlreadyRouted(exchange) || (!"ws".equals(scheme) && !"wss".equals(scheme))) {
        return chain.filter(exchange);
    }
    setAlreadyRouted(exchange);


    HttpHeaders headers = exchange.getRequest().getHeaders();
    HttpHeaders filtered = filterRequest(getHeadersFilters(),
            exchange);

    List<String> protocols = headers.get(SEC_WEBSOCKET_PROTOCOL);
    if (protocols != null) {
        protocols = headers.get(SEC_WEBSOCKET_PROTOCOL).stream()
                .flatMap(header -> Arrays.stream(commaDelimitedListToStringArray(header)))
                .map(String::trim)
                .collect(Collectors.toList());
    }

    return this.webSocketService.handleRequest(exchange,
            new ProxyWebSocketHandler(requestUrl, this.webSocketClient,
                    filtered, protocols));
}
8. Making An Exchange As Routed

上面一些像ForwardRoutingFilter、Websocket Routing Filter的源码中,都可以清楚看到gateway通过设置gatewayAlreadyRouted标识这个请求是否已经路由转发出去了,无需其他filter重复路由,这样就可以避免重复错误的路由操作,保证了路由的实现灵活性。

ServerWebExchangeUtils.isAlreadyRouted检查是否已被路由,ServerWebExchangeUtils.setAlreadyRouted标记已被路由状态。

五、其他的一些配置

1. TLS / SSL

Spring Cloud Gateway使用HTTPS,是和普通的Spring boot服务配置是一样的,比如:

application.yml.

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

Spring Cloud Gateway都可以路由转给给http和HTTPS的下游后端服务,如果是路由去HTTPS后端服务,gateway像下面一样配置信任所有下游服务:

application.yml.

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

当然这种配置,线上生成环境还是不太适合的,所以gateway可以配置自己的信任的证书列表:

application.yml.

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

Spring Cloud Gateway如果没有配置信任证书列表,则会拿系统默认的证书库(可以通过system property的javax.net.ssl.trustStore属性来修改系统默认证书库)。

TLS Handshake 当是用HTTPS来通讯时,http客户端就需要初始化TLS握手连接了,所以就需要配置握手连接时的超时配置:

application.yml.

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

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: http://example.org
        filters:
        - name: SetStatus
          args:
            status: 401
      - id: setstatusshortcut_route
        uri: http://www.google.com
        filters:
        - SetStatus=401

通常情况下,properties的配置就已经够用的了,但也有一些人的需求是从外部源来加载配置文件,比如数据库等,所以官方也承诺未来的版本会基于Spring Data Repositories实现Redis, MongoDB和Cassandra版本的RouteDefinitionLocator。

####### 2.1 Fluent Java Routes API 除了上面的配置文件配置外,也可以通过RouteLocatorBuilder的流式API来进行java实现配置。

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

这种用法就可以通过实行Predicate接口来定义更复杂的匹配规则,也可以用and()、or()和negate()来组合不同的匹配规则,灵活性会更大一点。

2.2 DiscoveryClient Route Definition Locator

通过服务发现客户端DiscoveryClient,gateway可以基于注册了的服务自动创建路由。 只需要配置spring.cloud.gateway.discovery.locator.enabled=true,以及引入DiscoveryClient的maven依赖即可,如:Netflix Eureka, Consul or Zookeeper。

Configuring Predicates and Filters For DiscoveryClient Routes 默认情况下gateway中的GatewayDiscoveryClientAutoConfiguration以及定义了一个predicate和filter的了。 默认的predicate是配置了/serviceId/**路径的path predicate,当然serviceId是DiscoveryClient里面的服务id。 默认的filter是配置了匹配参数/serviceId/(?.*)和替换参数/${remaining}的rewrite path filter,目的是将serviceId从path中去除掉,因为下游是不需要的。

你也可以自定义DiscoveryClient路由的predicate和filter,只需要设置spring.cloud.gateway.discovery.locator.predicates[x]和spring.cloud.gateway.discovery.locator.filters[y]即可,如下:

application.properties.

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}'"
3. Reactor Netty Access Logs

spring cloud gateway是没有打印access log的,但是底层的Reactor Netty是有的,在应用启动命名中增加设置-Dreactor.netty.http.server.accessLogEnabled=true来开启。 注:因为Reactor Netty不是基于spring boot的,所以它并不会去spring boot的配置中获取上面的配置,所以只能在Java System Property中获取。

可以在常用的日志系统中配置日志的打印文件和格式,如logback的配置:

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>
4. CORS Configuration

gateway是支持CORS的配置,可以通过不同的URL规则匹配不同的CORS策略:

application.yml.

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "http://docs.spring.io"
            allowedMethods:
            - GET
5. Actuator API

Spring Cloud Gateway也可以配置actuator来监控和操作一些功能点,增加下面的配置即可:

application.properties.

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway
5.1 查看filter信息

####### 5.1.1 Global Filters 使用GET请求gateway地址/actuator/gateway/globalfilters,就可以获取类似于下面的返回:

{
  "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
}

返回信息包含了gateway的使用中的global filters实例,包含了实例的toString()和order的keyvalue信息。

####### 5.1.2 Route Filters 使用GET请求gateway地址/actuator/gateway/routefilters,就可以获取类似于下面的返回:

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

返回信息里面包含了gateway中可以提供使用的GatewayFilter factories 详细信息,其中展示的是GatewayFilterFactory的实例toString()打印,及配置类。后面的null是某些GatewayFilter factory实现问题,本来是用来展示order的,但是GatewayFilter factory没有实现,就返回null了。

5.2 路由缓存刷新

使用POST请求gateway地址/actuator/gateway/refresh,并返回http状态码为200,标识刷新路由缓存成功。

5.3 查看路由定义信息

使用GET请求gateway地址/actuator/gateway/routes,获取类似下面的返回:

[{
  "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
}]

上面对象的定义如下表:

key value类型 value描述 route_id String 路由id. route_object.predicate Object Route Predicate route_object.filters Array GatewayFilter order Number 路由顺序 ####### 5.3.1 查看单个路由信息 如果是想只获取单个路由信息,则使用GET请求地址/actuator/gateway/routes/{id}即可。 5.3.2 创建和删除路由 创建路由,使用POST请求,并附带类似下面的json body,到/gateway/routes/{id_route_to_create}即可。

{
  "route_id": "second_route",
  "route_object": {
    "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
    "filters": []
  },
  "order": 0
}

删除路由,使用DELETE请求地址/gateway/routes/{id_route_to_delete}即可。

5.4 Actuator API汇总
IDHTTP MethodDescription
globalfiltersGET展示global filters信息
routefiltersGET展示GatewayFilter factories信息
refreshPOST刷新路由缓存
routesGET 展示路由定义信息
routes/{id}GET展示单个路由信息
routes/{id}POST添加新的路由
routes/{id}DELETE移除路由

开发指南 自定义GatewayFilter Factories 如果想自定义实现GatewayFilterFactory,可以继承AbstractGatewayFilterFactory抽象类。

比如如果想请求前做一些事情,可以类似于下面的实现:

*PreGatewayFilterFactory.java. *

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

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

	@Override
	public GatewayFilter apply(Config config) {
		// 从config对象中获取配置
		return (exchange, chain) -> {
            // 在这里做请求前的事情
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //重新构造新的request
            return chain.filter(exchange.mutate().request(request).build());
		};
	}

	public static class Config {
        // 设置配置
	}
}

请求后做的是事情,可以如下实现:

PostGatewayFilterFactory.java.

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

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

	@Override
	public GatewayFilter apply(Config config) {
		// 从config对象中获取配置
		return (exchange, chain) -> {
			return chain.filter(exchange).then(Mono.fromRunnable(() -> {
				ServerHttpResponse response = exchange.getResponse();
				// 在这里做请求后的操作实现
			}));
		};
	}

	public static class Config {
        // 设置配置
	}

}

网关配置实例

spring:
  cloud:
    gateway:
      # 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
      discovery:
        locator:
          ####开启以服务id去注册中心上获取转发地址
          enabled: true
      # 配置路由规则
      routes:
        #路由id
        - id: provider
          # 采用 LoadBalanceClient 方式请求,以 lb:// 开头,后面的是注册在 Nacos 上的服务名
          uri: lb://alibaba-nacos-provider
#          # 直接可以更url地址
#          uri: http://localhost:8081/
          # Predicate 翻译过来是“谓词”的意思,必须,主要作用是匹配用户的请求,有很多种用法
          predicates:
            # 通过HTTP的method来匹配路由,这里是匹配 GET 和 POST 请求
            - Method=GET,POST
            #使用的是path列表作为参数,使用Spring的PathMatcher匹配path,可以设置可选变量。
            - Path=/test/**,/foo/{segment},/bar/{segment}  #路由可以匹配诸如:/foo/1 或 /foo/bar 或 /bar/baz 或 /test/1 或  /test/1/1 等
            #使用的是时间作为匹配规则,只要当前时间大于设定时间,路由才会匹配请求
            - After=2018-12-25T14:33:47.789+08:00
            # 使用时间作为匹配规则,只要当前时间小于设定时间,路由才会匹配请求。
            - Before=2018-12-25T14:33:47.789+08:00
            #使用两个时间作为匹配规则,只要当前时间大于第一个设定时间,并小于第二个设定时间,路由才会匹配请求
            - Between=2018-12-25T14:33:47.789+08:00, 2018-12-26T14:33:47.789+08:00
            #使用的是cookie名字和正则表达式的value作为两个输入参数,请求的cookie需要匹配cookie名和符合其中value的正则。
            - Cookie=cookiename, cookievalue  #路由匹配请求存在cookie名为cookiename,cookie内容匹配cookievalue的
            #两个参数,一个header的name,一个是正则匹配的value。
            - Header=X-Request-Id, \d+  #路由匹配存在名为X-Request-Id,内容为数字的header的请求
            #使用的是host的列表作为参数,host使用Ant style匹配。
            - Host=**.somehost.org,**.anotherhost.org  #路由会匹配Host诸如:www.somehost.org 或 beta.somehost.org或www.anotherhost.org等请求。
            #通过一个或两个参数来匹配路由,一个是查询的name,一个是查询的正则value。
            - Query=baz  #匹配所有包含baz查询参数的请求。
            #- Query=foo, ba. #匹配所有包含ba,并且ba的内容为诸如:bar或baz等符合ba.正则规则的请求。
            # 通过无类别域间路由(IPv4 or IPv6)列表匹配路由。
            - RemoteAddr=192.168.1.1/24  #路由就会匹配RemoteAddr诸如192.168.1.10等请求。
        - id: ALIBABA-NACOS-FEIGN
          uri: lb://alibaba-nacos-feign
          predicates:
            - Method=GET,POST

全部评论: 0

    我有话说: