gateway配置

品书读茶發表於2024-03-05

【閘道器係統框架】腳手架專案

概述

【閘道器係統框架】專案是一個腳手架專案,來幫助開發同事快速搭建一個完整結構的閘道器層專案,開發者在生成的專案基礎上進行開發即可,以提高開發效率和程式碼質量。

【閘道器係統框架】專案功能主要體現在:

  • 不必從零開始搭建初始專案,提高開發效率
  • 路由功能
  • token認證 和 URL鑑權
  • 限流功能
  • 路徑重寫
  • 跨域配置
  • 透過 Feign 呼叫下游系統介面

路由功能

1、基於 Path 路徑的路由斷言

PathRoutePredicateFactory : 接收一個正則列表,根據路徑進行匹配,如果滿足規則,則轉發到配置的 uri 地址

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          # 路由跳轉地址
          uri: https://www.csdn.net
          predicates:
            - Path=/blog/{segment}, /edu/**

如上:/blog/1/blog/java/edu/php 等請求都將被匹配。

URI 模板變數 (如上例中的 segment ) 將以 Map 鍵值的方式儲存於 ServerWebExchange.getAttributes() 中,
可以在 GatewayFilterFactory 中使用。

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

2、基於 Query 請求引數的路由斷言

QueryRoutePredicateFactory : 接收兩個引數,一個請求引數(必傳)和一個正規表示式(可選),判斷請求引數是否具有給定名稱且值與正規表示式匹配。

spring:
  cloud:
    gateway:
      routes:
        - id: query_route
          uri: https://www.csdn.net
          predicates:
            # - Query=blog
            - Query=blog, java.*

如上,- Query=blog 會匹配包含請求引數 blog 的請求;
- Query=blog, java.* 會匹配請求中包含引數 blog,並且值以 java 開頭(java / java1 / java123 等)的請求。

3、基於 Method 請求方式的路由斷言

MethodRoutePredicateFactory : 匹配一個或多個 HTTP 請求方式(GET / POST / PUT / DELETE / HEAD 等)

spring:
  cloud:
    gateway:
      routes:
        - id: method_route
          uri: https://www.csdn.net
          predicates:
            - Method: GET,POST

所有 GET 請求和 POST 請求都將被路由

4、基於 Datetime 日期時間的路由斷言

此型別的斷言根據時間做判斷,主要有三個:

  1. AfterRoutePredicateFactory : 接收一個日期引數,判斷請求日期是否晚於指定日期
  2. BeforeRoutePredicateFactory : 接收一個日期引數,判斷請求日期是否早於指定日期
  3. BetweenRoutePredicateFactory : 接收兩個日期引數,判斷請求日期是否在指定時間段內
spring:
  cloud:
    gateway:
      routes:
        - id: datetime_route
          uri: https://www.csdn.net
          predicates:
            # - After=2021-08-30T23:59:59.789+08:00[Asia/Shanghai]
            # - Before=2021-09-30T23:59:59.789+08:00[Asia/Shanghai]
            - Between=2021-08-30T23:59:59.789+08:00[Asia/Shanghai], 2021-09-30T23:59:59.789+08:00[Asia/Shanghai]

5、基於 Weight 權重的路由斷言

WeightRoutePredicateFactory : 接收一個[組名, 權重],然後對同一個組內的路由按照權重轉發

spring:
  cloud:
    gateway:
      routes:
        - id: weight_route1
          uri: https://www.csdn.net
          predicates:
            - Path=/blog/**
            # blogGroup 是組名, 90 是權重
            - Weight=blogGroup, 90

        - id: weight_route2
          uri: https://www.cnblogs.com
          predicates:
            - Path=/blog/**
            # blogGroup 是組名, 10 是權重
            - Weight=blogGroup, 10

此斷言可用於實現灰度釋出等功能。

6、基於 Header 頭資訊的路由斷言

HeaderRoutePredicateFactory :接收兩個引數,header名稱和一個正規表示式。 判斷請求頭資訊中是否具有給定名稱且值與正規表示式匹配。

spring:
  cloud:
    gateway:
      routes:
        - id: header_route
          uri: https://www.csdn.net
          predicates:
            - Header=X-Request-Id, BLOG

匹配請求頭中,引數名稱為 X-Request-Id, 且值為 BLOG 的請求。

7、基於 Cookie 的路由斷言

CookieRoutePredicateFactory :接收兩個引數,cookie 名稱和一個正規表示式。 判斷請求 cookie 是否具有給定名稱且值與正規表示式匹配。

spring:
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: https://www.csdn.net
          predicates:
            - Cookie=UserName, 123456

8、基於 Host 的路由斷言

HostRoutePredicateFactory :接收一個正則域名列表。判斷請求的 Host 是否滿足匹配規則。

spring:
  cloud:
    gateway:
      routes:
        - id: host_route
          uri: https://www.csdn.net
          predicates:
            - Host=**.order.baidu.com, **.goods.baidu.com

9、基於 RemoteAddr 遠端地址的路由斷言

RemoteAddrRoutePredicateFactory :接收一個IP地址(格式為 ip/子網掩碼)列表,判斷請求主機地址是否在地址段中。

spring:
  cloud:
    gateway:
      routes:
        - id: remoteAddr_route
          uri: https://www.csdn.net
          predicates:
            - RemoteAddr=192.168.1.1/24, 192.168.0.100

如上,192.168.1.1 是IP地址,24是子網掩碼,如果沒有寫子網掩碼,預設為32(255.255.255.255)

token認證 和 URL鑑權

白名單

配置到白名單的 url,不需要進行token認證 和 URL鑑權。

示例如下:

jwt:
  # 無需進行 token 校驗的請求路徑列表,請求支援萬用字元和RESTFUL規範
  # 示例:
  # 1、/admin/sys/login (可以匹配 /admin/sys/login 和 /admin/sys/login )
  # 2、/admin/sys/login/*(可以匹配 /admin/sys/login/ 、 /admin/sys/login/1 和 /admin/sys/login/1/)
  # 3、/admin/sys/login/**(可以匹配 /admin/sys/login/ 、 /admin/sys/login/1 、 /admin/sys/login/1/ 和 /admin/sys/login/1/1 等)
  # 4、/admin/sys/login/? (可以匹配 /admin/sys/login/1 和 /admin/sys/login/1/)
  # 5、/admin/sys/login::POST(只能匹配 POST 請求方式)
  # 6、/admin/sys/login/?::POST(匹配 POST 請求方式的 /admin/sys/login/1 和 /admin/sys/login/1/)
  # 7、......
  allowedList:
    - /login    
    - /limit/**
    - /demo/allow/*::POST # 如果需要限制請求型別,則在請求地址後邊新增 [::請求型別]

token 認證

對不在白名單中的請求,會先進行 token 校驗。token 在 header 中進行傳輸,相關配置見 JwtTokenConfig。

jwt:
  secret: xxxxxxxx #JWT加解密使用的金鑰
  expiration: 1800 #JWT的超期限時間(60 * 30),單位s

token 續期

當 token 校驗透過後,會嘗試重新生成 token,如果重新生成 token 成功,則會將新 token 儲存到 response header 中。

生成邏輯為:原 token 沒有過期,並且剩餘有效時間小於總有效時間的一半時,會生成新 token。

設定全域性 header 資訊

閘道器層可以將下游微服務系統使用到的通用資訊儲存到 header 中,如下:

// 將下游系統需要使用的屬性,設定到 header 中
// 將下游系統需要使用的屬性,設定到 header 中
        ServerHttpRequest newRequest = exchange.getRequest().mutate()
                .header(JwtTokenConfig.HEADER_TOKEN_KEY, "")
                .header(GlobalHeaderConstant.USER_NAME_KEY, userName)
                .header(Request.USER_HEADER, UserJsonUtils.serialize(jwtTokenUtil.getUserFromToken(token)))
                .build();
                log.info("轉發後的header資訊[{}]",newRequest.getHeaders());

如需設定多個資訊,可以使用 exchange.getRequest().mutate().headers() 進行儲存設定

限流功能

# 限流示例
- id: limit_route
  uri: http://localhost:8080
  predicates:
    - Path=/limit/test
  filters:
    - StripPrefix=1
    - name: RequestRateLimiter
      args:
        # 使用SpEL按名稱引用bean
        key-resolver: "#{@ipKeyResolver}"
        # 令牌桶填充平均速率 (每秒最大訪問次數)
        redis-rate-limiter.replenishRate: 1
        # 令牌桶上限
        redis-rate-limiter.burstCapacity: 2

RequestRateLimiter 是限流過濾器,該過濾器需要配置三個引數:

  • burstCapacity,令牌桶總容量。
  • replenishRate,令牌桶每秒填充平均速率。
  • key-resolver,用於限流的鍵的解析器的 Bean 物件的名字。它使用 SpEL 表示式根據#{@beanName}從 Spring 容器中獲取 Bean 物件。

穩定速率是透過在 replenishRate 和 burstCapacity 中設定相同的值來實現的。可透過設定 burstCapacity 高於 replenishRate 來允許臨時突發流量。

路徑重寫

StripPrefix 去掉請求路徑的最前面 n個部分

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

請求 /name/blue/red 會轉發到 /red

PrefixPath 在請求路徑前新增字首

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://localhost:8080
        filters:
        - PrefixPath=/mypath

訪問/test 的請求被髮送到 http://localhost:8080/mypath/test

RedirectTo 重定向,配置包含重定向的返回碼和地址

spring:
  cloud:
    gateway:
      routes:
      - id: redirectTo_route
        uri: http://localhost:8080
        filters:
        - RedirectTo=302, http://localhost:8081

RewritePath 改寫路徑

spring:
  cloud:
    gateway:
      routes:
      - id: rewrite_filter
        uri: http://localhost:8080
        predicates:
        - Path=/test/**
        filters:
        - RewritePath=/where(?<segment>/?.*), /test(?<segment>/?.*)

/where/... 改成 /test/...

SetPath 設定請求路徑,與RewritePath類似

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: http://localhost:8080
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}

如 /red/blue 的請求被轉發到 /blue

SetRequestHeader 設定請求頭資訊

spring:  
  cloud:    
    gateway:      
      routes:      
        - id: setrequestheader_route        
          uri: http://localhost:8080        
          filters:        
            - SetRequestHeader=X-Request-Red, Blue

RemoveRequestHeader 去掉某個請求頭資訊

spring:  
  cloud:    
    gateway:      
      routes:      
        - id: removerequestheader_route        
          uri: http://localhost:8080        
          filters:        
            - RemoveRequestHeader=X-Request-Foo

去掉請求頭資訊 X-Request-Foo

RemoveRequestParameter 去掉某個請求引數資訊

spring:  
  cloud:    
    gateway:      
      routes:      
        - id: removerequestparameter_route        
          uri: http://localhost:8080        
          filters:        
            - RemoveRequestParameter=userName

Default-filters 對所有請求新增過濾器

spring:
  cloud:
    gateway:
      default-filters:
      - PrefixPath=/test

跨域配置

# 跨域配置
spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOriginPatterns: '*'
            allowedMethods: '*'
            allowedHeaders: '*'
            allowCredentials: true

相關文章