SpringCloud Gateway 服務閘道器的快速入門
前言
Spring Cloud Gateway 旨在提供一種簡單而有效的方式來路由到 API,併為它們提供橫切關注點,例如:安全性、監控/指標和彈性。 閘道器作為系統的唯一流量入口,封裝內部系統的架構,所有請求都先經過閘道器,由閘道器將請求路由到合適的微服務。文字僅僅簡單的介紹了對 Spring Cloud Gateway 的認識及使用。
1、Gateway 簡介
Gateway 閘道器官網連結: http://spring.io/projects/spring-cloud-gateway

1、閘道器的 核心功能特性 :
-
請求路由:一切請求都必須先經過 gateway,但閘道器不處理業務,而是根據某種規則,把請求轉發到某個微服務,這個過程叫做路由。當然路由的目標服務有多個時,還需要做負載均衡。
-
許可權控制:閘道器作為微服務入口,需要校驗使用者是是否有請求資格,如果沒有則進行攔截。
-
限流:當請求流量過高時,在閘道器中按照下流的微服務能夠接受的速度來放行請求,避免服務壓力過大。
2、架構圖:

2、Gateway 特點
-
基於 Spring Framework 5、Project Reactor 和 Spring Boot 2.0 構建
-
能夠匹配任何請求屬性的路由。
-
謂詞和過濾器特定於路由。
-
斷路器整合。
-
Spring Cloud Discovery 客戶端整合
-
易於編寫謂詞和過濾器
-
請求速率限制
-
路徑重寫
3、Gateway 快速入門
1、建立 gateway 服務
建立 SpringBoot 工程 gatewaway

2、引入依賴
引入依賴,nacos 和閘道器 gateway 的依賴。
<!--閘道器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服務發現依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
複製程式碼
3、編寫啟動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
複製程式碼
4、編寫配置檔案
編寫基礎配置和路由規則,建立 application.yml 檔案,內容如下:
server:
port: 10086 # 閘道器埠
spring:
application:
name: gateway # 服務名稱
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 閘道器路由配置
- id: user-service # 路由id,自定義,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
uri: lb://userservice # 路由的目標地址 lb就是負載均衡,後面跟服務名稱
predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
- Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
複製程式碼
我們將符合 Path
規則的一切請求,都代理到 uri
引數指定的地址。
本例中,我們將 /user/**
開頭的請求,代理到 lb://userservice
,lb 是負載均衡,根據服務名拉取服務列表,實現負載均衡。
5、測試
當訪問 http://localhost:10086/user/1 時,符合 /user/**
規則,請求轉發到 uri:http://user-service/user/1,得到了結果:

簡單來說,當來了一個請求時,都會經過閘道器判斷是否符合規則,如果符合規則則跳轉到相應地址。
4、斷言工廠
我們在配置檔案中寫的斷言規則只是字串,這些字串會被 Predicate Factory 讀取並處理,轉變為路由判斷的條件
例如 Path=/user/**是按照路徑匹配,這個規則是由
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory
類來
SpringCloudGateway 的斷言工廠在還有下面十幾個:
5、過濾器工廠
GatewayFilter 是閘道器中提供的一種過濾器,可以對進入閘道器的請求和微服務返回的響應做處理。
1、路由過濾器的種類
Spring 提供了很多種不同的路由過濾器工廠。例如:
2、請求頭過濾器
只需要修改 gateway 服務的 application.yml 檔案,新增路由過濾即可。配置如下:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
filters: # 過濾器
- AddRequestHeader= *** # 新增請求頭
複製程式碼
3、預設過濾器
如果要對所有的路由都生效,則可以將過濾器工廠寫到 default 下。配置如下:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
default-filters: # 預設過濾項
- AddRequestHeader= ***
複製程式碼
6、全域性過濾器
1、全域性過濾器作用
全域性過濾器的作用也是處理一切進入閘道器的請求和微服務響應,與 GatewayFilter 的作用一樣。
區別在於 GatewayFilter 通過配置定義,處理邏輯是固定的;而 GlobalFilter 的邏輯需要自己寫程式碼實現。
定義方式是實現 GlobalFilter 介面。
public interface GlobalFilter {
/**
* 處理當前請求,有必要的話通過{@link GatewayFilterChain}將請求交給下一個過濾器處理
*
* @param exchange 請求上下文,裡面可以獲取Request、Response等資訊
* @param chain 用來把請求委託給下一個過濾器
* @return {@code Mono<Void>} 返回標示當前過濾器業務結束
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
複製程式碼
在 filter 中編寫自定義邏輯,可以實現下列功能:
-
登入狀態判斷
-
許可權校驗
-
請求限流等
2、自定義全域性過濾器
定義全域性過濾器,攔截請求,判斷請求的引數是否滿足條件,引數中是否有 authorization,authorization 引數值是否為 admin,如果同時滿足則放行,否則攔截。
在 gateway 中定義一個過濾器,程式碼如下。
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.獲取請求引數
MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
// 2.獲取authorization引數
String auth = params.getFirst("authorization");
// 3.校驗
if ("admin".equals(auth)) {
// 放行
return chain.filter(exchange);
}
// 4.攔截
// 4.1.禁止訪問,設定狀態碼
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
// 4.2.結束處理
return exchange.getResponse().setComplete();
}
}
複製程式碼
3、過濾器執行順序
請求進入閘道器會碰到三類過濾器:
-
當前路由的過濾器
-
DefaultFilter
-
GlobalFilter
請求路由後,會將當前路由過濾器和 DefaultFilter、GlobalFilter,合併到一個過濾器鏈(集合)中,排序後依次執行每個過濾器。
排序的規則如下:
-
每一個過濾器都必須指定一個 int 型別的 order 值, order 值越小,優先順序越高,執行順序越靠前 。
-
GlobalFilter 通過實現 Ordered 介面,或者新增 @Order 註解來指定 order 值,由我們自己指定
-
路由過濾器和 defaultFilter 的 order 由 Spring 指定,預設是按照宣告順序從 1 遞增。
-
當過濾器的 order 值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter 的順序執行。
7、跨域問題
在 gateway 服務的 application.yml 檔案中,根據需求新增下面的配置。
spring:
cloud:
gateway:
globalcors: # 全域性的跨域處理
add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題
corsConfigurations:
'[/**]':
allowedOrigins: # 允許哪些網站的跨域請求
- "http://localhost:8090"
allowedMethods: # 允許的跨域ajax的請求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允許在請求中攜帶的頭資訊
allowCredentials: true # 是否允許攜帶cookie
maxAge: 360000 # 這次跨域檢測的有效期
複製程式碼
總結
API Gateway(APIGW / API 閘道器),是出現在系統邊界上的一個面向 API 的、序列集中式的強管控服務,這裡的邊界是企業 IT 系統的邊界,可以理解為 企業級應用防火牆,主要起到 隔離外部訪問與內部系統的作用。簡單來說,當來了一個請求時,都會經過閘道器,進行把關。在微服務概念的流行之前,API 閘道器就已經誕生了,例如銀行、證券等領悅常見的前置機系統,它也是解決訪問認證、報文轉換、訪問統計等問題的。 最後,每日毒雞湯:"三人省力,四人更簡單,眾人團結緊,百事能成功。"
- 那些 Go 語言發展歷史上的重大決策
- 從趨勢到挑戰,一站式解讀作業系統運維和可觀測性
- 百萬級 Topic,騰訊雲的 Apache Pulsar 穩定性實踐
- Apache Doris 在思必馳的應用優化實踐:海量語音通話資料下,實時、離線一體的數倉架構設計實踐
- 愛數正式開源認知智慧開發框架 KWeaver
- 運維智慧化的三大關鍵技術
- “抄我的還‘反捅’我一刀”,Gary Marcus 發文駁斥圖靈獎得主 Yann LeCun
- 當出海成為必選項,企業如何構建全場景全生態技術底座?
- 數智底座必備能力三:快速構建創新應用
- Docker 多階段構建實戰 (multi-stage builds)
- 工作筆記之 SELECT 語句在 SAP ABAP 中的用法總結(上)
- 經久不衰的設計定律是不要讓我思考的設計
- 不要指望下一個像 GPT 這樣的大型語言模型會民主化
- Java 近期新聞:Helidon Níma、Spring Framework、MicroProfile、MicroStream、Kotlin 和 Piranha
- 一文入門 jQuery
- C 學習 ---__libc_open 函式的原理
- 監控系統工作原理
- 甲骨文新微服務框架 Helidon Níma:使用虛擬執行緒實現高效能
- 【雲原生 | 從零開始學 Kubernetes】二、使用 kubeadm 搭建 K8S 叢集
- Elasticsearch 聚合學習之四:結果排序