Spring Cloud Gateway 入门一

1,070 阅读9分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


Spring Cloud Gateway是Spring官方提供了高性能网关。Spring Cloud Gateway为微服务架构提供一种简单有效的统一的API路由管理方式。作为统一的流量入口,可以在Spring Cloud Gateway中完成负载均衡日志追踪安全认证等功能。

工作模型

Spring Cloud Gateway的本质是服务代理,即服务不在请求具体的应用服务,而是统一请求Gateway网关,由网关根据匹配规则将请求路由到具体的应用服务。下图是官网给出的工作原理图:

image.png

客户端Spring Cloud Gateway发出请求,Spring Cloud Gateway通过Gateway Handler Mapping进行 路由配置,匹配到路由之后,请求进入Gateway Web Handler处理。Gateway Web HandlerGateway提供的一组过滤器

基本组成

**Route **:网关的基础。由ID目标URI、一组Predicate和一组Filter构成。如果所有的Predicate 都为true,则将请求路由到目标URI Predicate:函数式接口。可以匹配来自HTTP请求的任何内容,例如请求方法、请求头、请求参数等。 Filter: 过滤器。可以在请求路由到目标URI之前或之后修改请求和响应。

Route

image.png

路由是网关的基本组成,包含iduripredicatesfiltersmetadata(元数据)属性。

  • id: 路由的唯一标识
  • uri:目标URI, Predicate集合都为true时,将原请求路由到的目标URI
  • predicates: 断言集合,可以根据datetime(请求时间) CookieHeaderHost(主机地址)、-- Method(请求方法)Path(请求路径)Query(查询参数)RemoteAddr(远程地址)Weight(路由权重)进行判断
  • filters: 这个filter内置的网关过滤器。包含添加或过滤Header参数响应数据请求路径以及CircuitBreaker 断路器RequestRateLimiter 限流等功能
  • metadata: 元数据,一般是一些描述信息

Predicate

Predicate的作用是判断请求是否和该Route匹配,如果匹配则将该请求路由到目标URISpring Cloud Gateway提供了一下Predicate Factory: image.png

  • After Predicate/Before Predicate/Between Predicate: 判断请求时间是否在跟定时间之前、之后或之间 After
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

Before

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

Between

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
  • Cookie Predicate: 根据Cookie匹配 Cookie Predicate接受两个参数,Cookie名称和regexp(一个Java正则表达式)。即具有给定名称的Cookie且其值与正则表达式匹配
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=name, value
  • Header Predicate: 根据请求头匹配 Header Predicate接受两个参数,Header名称和regexp(一个Java正则表达式)。即具有给定名称的Header且其值与正则表达式匹配
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+   # 请求头中具有名为X-request-Id的标头,且其值与\d+正则表达式匹配(即,其值为一个或多个数字)
        
  • Host Predicate: 根据主机地址匹配 Host Predicate接受一个参数:主机名模式列表。该模式是Ant-style风格: ?: 匹配任何单字符, *: 匹配0或者任意数量的字符, **: 匹配0或者更多的目录
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
  • Method Predicate: 根据请求方法匹配 接受一个参数(如GETPOSTDELETE等),匹配多个方法时以逗号隔开
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST
  • Path Predicate: 根据请求路径匹配 接受一个参数:请求路径。支持Ant-style风格,匹配多个路径时以逗号隔开
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/book/{id}  # /book/1、/book/2等都可以匹配成功
  • Query Predicate: 根据请求参数匹配 接受两个参数:一个必需的参数和一个可选的regexp(这是一个Java正则表达式)
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green  # 请求参数包含green,则匹配成功
  • RemoteAddr Predicate:根据请求中的远程地址匹配 接受一个参数:CIDR模式的ip源。CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24
  • Weight Predicate: 配置路由的权重,根据权重选择Route 接受两个参数:group (分组)和Weight(权重)
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

Filter

Filter主要用来修改请求或响应信息如请求路径、请求参数、响应头、响应结果等。Spring Cloud Gateway 提供的内置Filter如下: image.png

  • AddRequestHeader Filter:增加请求头 接收一个namevalue参数,将namevalue放入该请求的请求头中
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue  # 向请求中添加一个名为`X-Request-red`值为`blue`的请求头
  • AddRequestParameter Filter: 添加参数 接收一个namevalue参数,将namevalue放入该请求的请求参数中
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=color, blue  # 向请求中添加`color=blue`参数

= AddResponseHeader Filter: 添加响应头 接收一个namevalue参数,将namevalue放入该请求的响应头中

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Blue 
  • DedupeResponseHeader Filter: 移除重复的响应头 接收以一个参数:请求头。要移除多个重复请求头时用空格隔开
spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin  # 当网关CORS逻辑和下游逻辑都添加了访问控制允许凭据和访问控制允许源响应头时,将删除它们的重复值
  • CircuitBreaker Filter: 断路器。当请求超时或出现异常时进行降级 Spring Cloud Gateway Spring Cloud CircuitBreaker一起完成CircuitBreaker,其中Spring Cloud CircuitBreaker支持多种CircuitBreaker库。。Resilience4J-开箱即用的CircuitBreaker库。
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker  在java中配置的CircuitBreaker bean
            fallbackUri: forward:/inCaseOfFailureUseThis  # 请求失败后调用, 可以不写
            statusCodes:  # 请求失败时返回的请求状态码, 可以不写
              - 500
              - "NOT_FOUND"

  • FallbackHeaders Filter: 在转发到外部应用程序中的fallbackUri的请求的标头中添加Spring Cloud CircuitBreaker执行的异常详细信息
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
  • MapRequestHeader Filter:映射请求头 接收两个参数:fromHeadertoHeader。如果请求中包含名为fromHeader的Header,则在请求中添加名为toHeader的Header,值为fromHeader的值
spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        - MapRequestHeader=fromHeader, toHeader
        
  • PrefixPath Filter: 在请求路径中添加前缀路径
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath  # 在请求路径中添加/mypath前缀。即对/hello的请求将被发送到/mypath/hello
  • PreserveHostHeader Filter: 保持Host Header 没有参数。设置路由筛选器检查的请求属性,以确定是否应发送原始Host Header,而不是HTTP客户端确定的Host Header
spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: https://example.org
        filters:
        - PreserveHostHeader
  • RequestRateLimiter Filter: 请求限流 RequestRateLimiter使用RateLimiter接口的实现类来确定是否允许当前请求继续进行。c请求速率超出设置时默认返回HTTP 429状态-太多请求

RequestRateLimiter接受可选的keyResolver参数和RateLimiter参数,如下图: image.png

RedisRateLimiter:基于RedisRateLimiter

Spring Cloud Gateway提供了基于Redis的限流实现-RedisRateLimiter

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   # 一个请求需要多少令牌。这是每个请求从bucket中提取的令牌数,默认为1
  • RedirectTo Filter: 重定向到指定请求 接受两个参数: statusurlstatus应该是300系列的重定向HTTP状态码(如301)。
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org 
  • RemoveRequestHeader Filter: 移除指定请求头 接受一个参数:header 名。删除请求头中该header
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo
  • RemoveResponseHeader Filter:移除请求参数
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red

同上

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo
  • RemoveRequestParameter Filter:移除请求参数 接受一个参数:参数名。
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red
  • RewritePath Filter:重写请求路径 接受两个参数: 匹配path regexp和替换path regexp。使用Java正则表达式来灵活地重写请求路径
spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        - RewritePath=/red/?(?<segment>.*), /${segment}  # 请求/red/a的路径将被替换成/a
        
  • RewriteLocationResponseHeader Filter: 修改位置响应标头的值,通常是为了去除后端特定的详细信息。它采用stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数
spring:
  cloud:
    gateway:
      routes:
      - id: rewritelocationresponseheader_route
        uri: http://example.org
        filters:
        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
  • RewriteResponseHeader Filter:重写响应头 接受三个参数:header 名称regexp替换参数。使用Java正则表达式灵活地重写响应头值
spring:
  cloud:
    gateway:
      routes:
      - id: rewriteresponseheader_route
        uri: https://example.org
        filters:
        - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
  • SaveSession Filter: 保存Session 不接受参数,在向下游转发请求之前强制执行WebSession::save操作
spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: https://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession
  • SecureHeaders Filter:向响应中添加一些安全相关的请求头

  • SetPath Filter:通过模板的方式改写请求路径

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}  # 路径/red/{segment}被改写成/{segment}。例如请求/red/test将变成请求/test
  • SetRequestHeader Filter: 设置请求头

  • SetResponseHeader Filter:设置响应头

  • SetStatus Filter:设置HTTP 响应码

  • StripPrefix Filter: 去除请求路径前缀 接受一个参数:层级数。去除指定层级的路径前缀

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

  • SetRequestHostHeader Filter:设置请求Host

  • ModifyRequestBody Filter: 修改请求体

需要使用java bean 配置

  • ModifyResponseBody Filter:修改响应体

需要使用java bean 配置

  • Token Relay Filter: Token中继过滤器

  • Default Filters: 默认过滤器,应用于所有路由

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

全局Filter

Spring Cloud Gateway提供了一个全局过滤器接口GlobalFilterGlobalFilter接受两个参数:ServerWebExchangeGatewayFilterChain,代表请求和响应。一些通用操作可以如(鉴权、记录日志等)可以通过实现GlobalFilter接口完成。

GlobalFilter通常和Ordered接口一齐实现

GlobalFilter默认实现类

Spring Cloud GatewayGlobalFilter提供了如下实现类: image.png