Spring?Gateway基礎教程
本文主要總結Spring Gateway的基礎用法,內容包括網關、Spring Gateway工作流程、Spring Cloud Gateway搭建、路由配置方式、負載均衡實現、斷言工廠這幾個部分
1. 網關
1.1 網關介紹
在微服務架構中,一個系統(tǒng)會被拆分為多個微服務,那么作為客戶端如何去調用這些微服務呢?如果沒有網關的存在,我們只能在客戶端記錄每個微服務的地址,然后分別去調用,這樣會產生很多問題:
- 客戶端多次請求不同的微服務,增加了客戶端代碼或配置編寫的復雜性
- 認證復,每個微服務需要獨立認真
- 存在跨域問題,在一定場景下處理相對復雜
為了解決上述問題引入了網關概念:所謂的API網關就是指系統(tǒng)的統(tǒng)一入口,提供內部服務的路由中轉,為客戶端提供統(tǒng)一的服務,一些與業(yè)務本身功能無關的公共邏輯可以在這里實現,例如認證、鑒權、監(jiān)控、路由轉發(fā)等。
1.2 網關對比
Zuul、Nginx+Lua 和 Spring Cloud Gateway 都可以用作API網關,但它們在不同方面有一些不同之處,包括性能、擴展性、功能和用途。以下是它們的主要比較:
- Zuul: 2. 性能:Zuul性能較低,特別是在處理大量并發(fā)請求時。它使用的是阻塞I/O,每個請求都會占用一個線程。 3. 擴展性:Zuul的擴展性相對較低。定制功能需要使用過濾器,這可能不夠靈活。 4. 功能:Zuul是Netflix OSS的一部分,提供基本的路由、負載均衡、重試等功能。然而,它的功能相對有限。 5. 用途:適合小規(guī)模的、非高并發(fā)的應用,或者作為微服務架構中的較早版本API網關。
- Nginx+Lua: 2. 性能:Nginx以其出色的性能而聞名。Nginx+Lua的組合可以在處理高并發(fā)請求時提供高性能,特別適合于需要低延遲的應用。 3. 擴展性:Nginx+Lua提供了強大的擴展性。使用Lua腳本,你可以定制和擴展其功能以適應各種需求。 4. 功能:Nginx是一個功能強大的反向代理服務器,可以處理負載均衡、緩存、SSL終端、請求重寫、安全性等各種功能。 5. 用途:適合高并發(fā)的生產環(huán)境,特別是需要高性能和低延遲的應用,一般用于一層網關。
- Spring Cloud Gateway: 2. 性能:Spring Cloud Gateway在性能方面表現不錯,它使用基于反應性的編程模型,充分利用非阻塞I/O。 3. 擴展性:Spring Cloud Gateway提供了很好的擴展性,它是基于Spring Framework構建的,因此可以與Spring生態(tài)系統(tǒng)的其他組件無縫集成。 4. 功能:Spring Cloud Gateway提供了路由、過濾器、限流、熔斷等功能,可以滿足大多數API網關的需求。 5. 用途:適合構建微服務架構中的API網關,特別是在使用Spring Boot和Spring Cloud的應用中。
1.3 Spring Gateway
Spring Cloud Gateway是一個用于構建API網關的開源項目,它是Spring Cloud生態(tài)系統(tǒng)的一部分。API網關是微服務架構中的關鍵組件之一,用于管理和路由傳入的請求,提供了一種集中化的訪問點,可以實現諸如路由、負載均衡、身份驗證、安全性、監(jiān)控、限流、重試等功能。Spring Cloud Gateway提供了一種現代、動態(tài)、靈活且功能強大的方式來處理這些任務。
以下是Spring Cloud Gateway的一些主要特點和功能:
- 動態(tài)路由:Spring Cloud Gateway允許你根據需要動態(tài)配置路由,這意味著你可以在不停止網關的情況下修改路由規(guī)則。路由配置通常存儲在配置中心(如Spring Cloud Config)中,從而實現靈活的路由管理。
- 過濾器:Gateway提供了一組預定義的過濾器,用于請求和響應的修改、校驗、驗證和監(jiān)控。你還可以編寫自定義過濾器以適應特定需求。
- 負載均衡:Gateway集成了Spring Cloud LoadBalancer,可實現請求的負載均衡。你可以將請求路由到多個后端服務實例,實現高可用和擴展性。
- 限流和熔斷:Spring Cloud Gateway支持通過集成Hystrix來實現限流和熔斷功能,以保護后端服務免受過多的請求壓力。
- 安全性:可以與Spring Security或其他身份驗證和授權機制集成,實現安全的API訪問。
- 監(jiān)控和指標:Spring Cloud Gateway集成了Spring Boot Actuator,提供了各種有用的監(jiān)控和度量信息,可以使用Micrometer將這些信息導出到多個監(jiān)控系統(tǒng)。
- WebSockets支持:Gateway支持WebSockets,因此可以處理實時通信的需求。
- HTTP/2支持:可以通過配置啟用HTTP/2協(xié)議,以提高性能。
- 自定義路由規(guī)則:除了使用配置外,你還可以編寫自定義的路由規(guī)則,以實現更復雜的路由需求。
Spring Cloud Gateway是建立在Spring Framework和Spring Boot的基礎上的,因此與Spring生態(tài)系統(tǒng)的其他組件無縫集成。它為構建微服務架構中的API網關提供了靈活、高性能和現代的解決方案。
特點:
- 性能強大:是Zuul性能的1.6倍
- 功能強大:內置了很多實用功能,如轉發(fā)、監(jiān)控、限流等
- 設計優(yōu)雅,易于拓展
1.4 核心概念
在Spring Gateway中:
- 路由(Route):路由是網關的基本構建單元,包括以下屬性:
- ID(標識):路由的唯一標識。
- URI(目標URI):定義路由請求將被轉發(fā)到的目標URI。
- 斷言(Predicates):一組謂詞,用于匹配HTTP請求的屬性,如路徑、主機、標頭等。
- 過濾器(Filters):一組過濾器,用于在請求到達目標URI之前或響應返回之前對請求和響應進行修改。
- 舉例:定義一個路由,將匹配
/example
路徑的請求,將其轉發(fā)到http://example.com
:
id: example_route uri: example.com predicates:
- Path=/example
斷言(Predicate):謂詞是用于匹配HTTP請求的條件。謂詞可以基于請求的各種屬性,如路徑、主機、標頭等。例如,Path
謂詞可以匹配請求路徑。
舉例:定義一個謂詞,要求請求路徑必須以/api
開頭:
predicates:
- Path=/api/**
- 過濾器(Filter):過濾器是網關中的處理器,它們可以在請求到達目標URI之前或響應返回之前對請求和響應進行修改。過濾器可以用于添加標頭、修改請求體、記錄日志等操作。
舉例:定義一個過濾器,向響應標頭中添加X-Custom-Header
標頭:
filters:
- AddResponseHeader=X-Custom-Header, Gateway
這些組件一起構成了Spring Gateway的核心功能,允許您定義路由規(guī)則、請求匹配條件以及請求和響應的處理操作。
1.6 總結
SpringCloud Gateway使用的是WebFlux中的reactor-netty響應式編程組件,底層使用Netty通訊框架。
2. Spring Gateway工作流程
2.1 官網上的核心工作流程
核心流程圖如下:
核心流程:
- 客戶端(Gateway Client)向 Spring Cloud Gateway發(fā)送請求。
- 如果Gateway Handler Mapping確定請求與路由匹配,則將其發(fā)送到Gateway Web Handler處理程序。
- 接著處理程序通過特定于請求的Filter鏈過濾請求。Filter被虛線分隔的原因是Filter可以在發(fā)送代理請求之前(pre)和之后(post)運行邏輯。執(zhí)行所有pre過濾器邏輯,然后進行代理請求,發(fā)送代理請求之后,運行“post”過濾器邏輯
- 過濾器作用:
- Filter在pre類型的過濾器可以做參數校驗,權限校驗、流量監(jiān)控、日志輸出和協(xié)議轉換等。
- Filter在Post類型的過濾器可以做響應內容、響應頭的修改、日志輸出和流量監(jiān)控等
核心點:
- Route(路由):路由是構建網關的基礎模塊兒,它由ID,目標URI,包括一系列的斷言喝過濾器組成,如果斷言為True則匹配該路由。
- Predicate(斷言):開發(fā)人員可以匹配http請求中的所有內容(如:請求頭或請求參數),請求與斷言匹配則進行路由。
- Filter(過濾):指Spring框架中GatewayWayFilter的實例,使用過濾器可以在請求被路由前或者之后對請求進行修改。
- 三個核心點連起來:當用戶的請求到達Gateway,Gateway會通過一些匹配條件,定位到真正的服務節(jié)點,并在這個轉發(fā)過程前后,進行一些細化控制。其中Predicate就是我們的匹配條件,Filter可以理解為一個過濾器,有了這兩點,再加上目標URI就可以實現一個具體路由了
2.2 Spring Gateway執(zhí)行流程
如上圖所示,當使用Spring Gateway處理請求時,它經歷以下流程:
- Client向Gateway Server發(fā)送請求: 客戶端(例如瀏覽器、移動應用或其他服務)發(fā)送HTTP請求到Spring Gateway服務器,這是請求的起始點。
- 請求會被HttpWebHandlerAdapter提取組裝成網關上下文:
- 請求進入Spring Gateway后,首先被HttpWebHandlerAdapter處理。這個組件負責提取HTTP請求信息,并將其組裝成網關上下文對象,其中包括請求的各種信息,如HTTP頭、請求參數等。
- 網關上下文會傳遞到DispatcherHandler:
- 組裝好的網關上下文被傳遞到DispatcherHandler,它是Spring Gateway的核心處理器。DispatcherHandler的任務是將請求分發(fā)到合適的處理程序。
- RoutePredicateHandlerMapping負責路由查找,并根據路由斷言判斷路由是否可用:
- RoutePredicateHandlerMapping負責路由查找,它將根據網關上下文中的信息選擇適當的路由。每個路由都包括一個或多個路由斷言,這些斷言是用來判斷該路由是否適用于當前請求的條件。
- 如果斷言成功,由FilteringWebHandler創(chuàng)建過濾器鏈并調用:
如果路由斷言成功,表示當前請求匹配了某個路由規(guī)則。此時,將會由FilteringWebHandler創(chuàng)建一個過濾器鏈,并按照鏈的順序調用這些過濾器。過濾器可以在請求到達后端服務之前或響應返回給客戶端之前對請求進行修改、驗證或記錄日志等操作。
這個流程允許Spring Gateway進行請求的路由和過濾,以實現對請求的控制和處理。通過配置不同的路由規(guī)則和過濾器,可以根據請求的性質來決定如何處理請求,例如路由到不同的后端服務、添加安全性措施或改變請求和響應的內容。
總結
Gateway的核心流程就是:路由轉發(fā)+執(zhí)行過濾器鏈
3. Spring Cloud Gateway搭建
3.1 Gateway搭建
搭建一個cloud-alibaba-gateway項目,因為使用了spring cloud 所以需要注意版本間的匹配,這里可以通過阿里的云原生腳手架去獲取適合的版本:[start.aliyun.com/]
搭建Spring Gateway項目之前需要一些前置搭建微服務注冊中心(Nacos,Consul,Eureka等),這里我使用Nacos進行演示,Nacos的搭建流程可以參考:[http://chabaoo.cn/article/184641.htm]
該案例的完整代碼可以在gitee項目中獲?。?a target="_blank">[gitee.com/lei-qinghua…]
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ts</groupId> <artifactId>cloud-alibaba-gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <name>cloud-alibaba-gateway</name> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.6.13</spring-boot.version> <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version> <spring-cloud.version>2021.0.5</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.ts.demo.DemoApplication</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
注意:引入Gateway一定要刪除spring-boot-starter-web依賴,否則會發(fā)生沖突無法引入。
yml
server: port: 9999 spring: application: name: cloud-gateway-service cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true # 開啟了spring gateway routes: - id: nacos-provider #服務id,對應nacos中注冊的服務名 uri: http://localhost:9003/nacos-provider #訪問的uri地址 predicates: - Path=/ts/** #斷言,對請求進行匹配,只有包含/ts的路徑才能通過斷言
controller (微服務cloud-alibaba-provider-9003)
這里我們搭建了另外一個微服務cloud-alibaba-provider-9003作為服務的提供者來驗證網關是否生效,這個微服務的邏輯非常簡單,使用HashMap模擬一個一個數據庫的獲取操作如下:
@RequestMapping("/ts") @RestController public class DataController { @Value("${server.port}") String serverPort; public static HashMap<Long,String> hashMap = new HashMap<>(); static { hashMap.put(1l,"鼠標"); hashMap.put(2l,"鍵盤"); hashMap.put(3l,"耳機"); } @GetMapping("info/{id}") public JsonResult<String> msbSQL(@PathVariable("id") Long id) { JsonResult<String> result = new JsonResult<>(200,"ServerPort: "+serverPort+":"+hashMap.get(id)); return result; } @GetMapping("/timeout") public JsonResult<String> timeout(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); } return new JsonResult<>(200,"ServerPort: "+serverPort); } }
測試:[http://localhost:9999/ts/timeout]
如下圖所示,我們通過微服務提供者的url對服務進行訪問,而是通過gateway網關的路徑對微服務進行訪問成功了,就說明我們的網關搭建成功了。
3.2 總結
這里以一個簡單的例子展示了Spring Gateway網關的基礎搭建和測試過程,相關的服務搭建都是在本地完成的,完整的代碼請參考我的gitee項目:[gitee.com/lei-qinghua…]
4. Gateway路由配置方式
在第三節(jié)中我們用yml文件對Gateway的路由方式進行了配置,實際上Gateway還可以通過Java代碼的方式來進行路由配置。
4.1 Gateway Config
通過@Bean 注入一個RouteLocator,代碼如下:
package com.example.cloudalibabagateway.config; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){ RouteLocatorBuilder.Builder routes =routeLocatorBuilder.routes(); routes.route("path_ts",r -> r.path("/ts/**").uri("http://localhost:9003/nacos-provider")); return routes.build(); } }
4.2 通過yml文件配置
server: port: 9999 spring: application: name: cloud-gateway-service cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true routes: - id: nacos-provider uri: http://localhost:9003/nacos-provider predicates: - Path=/ts/**
5. Gateway實現負載均衡
5.1 什么是負載均衡
微服務系統(tǒng)的負載均衡是一種機制,用于在微服務架構中均勻分配網絡請求和流量到不同的微服務實例,以確保各個服務的資源充分利用,提高系統(tǒng)的性能、可用性和穩(wěn)定性。在微服務架構中,通常存在多個相同或相似的微服務實例,每個實例都提供相同的服務接口,但可能運行在不同的主機或容器上。
以下是微服務系統(tǒng)中負載均衡的一些關鍵概念和特點:
- 服務實例均衡分配:微服務負載均衡確保來自客戶端的請求均勻分布到不同的服務實例上,以防止某些實例過載而其他實例處于空閑狀態(tài)。
- 多種負載均衡策略:微服務負載均衡可以采用不同的策略,如輪詢、隨機、最少連接等,以選擇目標服務實例。每種策略有其用途,根據具體情況選擇合適的策略。
- 健康檢查:負載均衡器定期檢查每個服務實例的健康狀態(tài),以確定哪些實例可以接收請求。如果某個實例不健康或不可用,負載均衡器將停止將請求路由到該實例。
- 自動擴展:微服務系統(tǒng)的負載均衡應該支持自動擴展。當系統(tǒng)負載增加時,可以自動添加新的服務實例以處理更多請求。這有助于應對流量波動和系統(tǒng)的橫向擴展。
- 故障轉移:如果某個服務實例出現故障,負載均衡器應該自動將流量轉移到其他健康的實例,以確保系統(tǒng)的可用性。
- 會話粘附:在某些情況下,需要確保同一客戶端的多個請求被路由到同一服務實例,以維護會話一致性。這稱為會話粘附,一些負載均衡器支持此功能。
微服務系統(tǒng)的負載均衡是確保整個系統(tǒng)運行順暢的重要組成部分。它有助于避免單點故障,提高系統(tǒng)的可用性,并允許系統(tǒng)根據需求自動擴展。選擇適當的負載均衡策略和工具對于構建穩(wěn)健的微服務系統(tǒng)至關重要。
5.2 自動負載均衡
Gateway還提供了和Zuul類似的自動路由規(guī)則,具體配置如下:
- gateway.discovery.locator.enabled = true 這個配置默認為false,但是如果設置為true就是開啟了通過serviceID轉發(fā)到具體的服務實例。
- 配置好之后,可以直接通過服務名稱來進行訪問Nacos中注冊的服務和對應接口。
- Gateway在開啟了自動路由之后還自帶負載均衡功能。
server: port: 9999 spring: application: name: cloud-gateway-service cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true # 開啟自動路由功能,根據服務名自動創(chuàng)建routes
測試:[http://localhost:9999/nacos-provider/info/1]
我們直接通過spring gateway的服務地址和服務提供者nacos-provider的服務名組成的url地址,就可以以負載均衡的方式訪問nacos-provider的服務。
5.3 手動負載均衡
自動負載均衡存在一個問題就是需要暴露每一個服務的服務名稱,因此可以采用手動負載均衡的方式來避免暴露微服務的服務名稱。
yml配置:
server: port: 9999 spring: application: name: cloud-gateway-service cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true routes: - id: nacos-provider uri: lb://nacos-provider # 開啟負載均衡,服務名稱為nacos-provider predicates: # 斷言,放開所有路徑 - Path=/**
- lb:// 代表開啟負載均衡
- 測試:[http://localhost:9999/info/1]
6. Gateway斷言Predicate
Gateway斷言可以理解為當滿足條件后才會進行轉發(fā),總結就是Predicate就是為了實現一組匹配規(guī)則,讓請求過來找到相應的Route進行處理。
6.1 斷言種類
Spring Cloud Gateway支持多種路由斷言(Route Predicates)類型,用于匹配和路由HTTP請求。以下是一些常見的路由斷言類型:
Path Route Predicate(路徑匹配):根據請求的路徑進行匹配。
predicates:
Path=/api/**
這將匹配所有以/api/
開頭的路徑。
Host Route Predicate(主機匹配):根據請求的主機名進行匹配。
predicates:
Host=example.com
這將匹配主機名為example.com
的請求。
Method Route Predicate(HTTP方法匹配):根據HTTP請求方法進行匹配。
predicates:
Method=GET
這將匹配HTTP GET請求。
Header Route Predicate(請求頭匹配):根據請求頭信息進行匹配。
predicates:
Header=Authorization, Bearer .+
這將匹配包含Authorization
頭且值以Bearer開頭的請求。
Query Route Predicate(查詢參數匹配):根據請求的查詢參數進行匹配。
predicates:
Query=name, john
這將匹配包含name=john
的查詢參數的請求。
Cookie Route Predicate(Cookie匹配):根據請求的Cookie信息進行匹配。
predicates:
Cookie=sessionId, .+
這將匹配包含名為sessionId
的Cookie的請求。
Combining Predicates(組合匹配):你可以組合多個路由斷言來創(chuàng)建更復雜的匹配條件。
- predicates:
- Path=/api/**Host=example.com
這將匹配主機為example.com
且路徑以/api/
開頭的請求。
這些路由斷言允許你根據請求的不同屬性(如路徑、主機、請求頭、HTTP方法等)進行匹配和路由,從而更靈活地控制請求的路由和處理。你可以在Spring Cloud Gateway的路由配置中定義這些路由斷言,以滿足你的具體需求。
7. Gateway的Filter
路由過濾器允許以某種方式修改傳入的http請求或傳出的HTTP響應,路由過濾器的范圍是特定的路由Spring Cloud Gateway包含許多內置的Gateway Filter工廠。
7.1 內置Filter
7.1.1 內置過濾器分類
Gateway內置的Filter生命周期分為兩種:pre(業(yè)務邏輯之前)、post(業(yè)務邏輯之后)
Gateway本身自帶的Filter分為2種:GateWayFilter(單一)、GlobalFilter(全局)
Spring Cloud Gateway提供了多個內置的過濾器(Filters),這些過濾器允許你在請求和響應的生命周期中執(zhí)行各種操作,例如請求路由、修改請求和響應、增加頭信息等。以下是一些常見的內置過濾器:
- Forward Routing Filter:用于路由請求到后端服務。
- LoadBalancerClient Filter:通過LoadBalancerClient執(zhí)行負載均衡請求。
- AddRequestHeader Filter:在請求中添加頭信息。
- AddRequestParameter Filter:在請求中添加查詢參數。
- RewritePath Filter:重寫請求路徑,用于修改請求的路徑。
- SetStatus Filter:設置HTTP響應狀態(tài)碼。
- AddResponseHeader Filter:在響應中添加頭信息。
- Hystrix Filter:用于Hystrix斷路器的支持。
- WebSockets Filter:用于WebSocket代理。
- ModifyResponseBody Filter:修改響應體內容。
- PreserveHostHeader Filter:保留原始主機頭信息。
- RequestRateLimiter Filter:實現請求速率限制。
這些內置過濾器可以通過Spring Cloud Gateway的路由配置文件進行配置,從而對請求和響應進行自定義處理。你可以根據具體需求組合和配置這些過濾器,以滿足你的應用程序的需求。此外,你也可以編寫自定義過濾器來執(zhí)行更高度定制的操作。過濾器在Gateway中扮演了非常重要的角色,幫助你實現請求的路由和處理邏輯。
7.1.2 內置過濾器配置
Spring Gateway提供了許多內置的過濾器,用于執(zhí)行常見的網關任務,例如鑒權、請求轉發(fā)、重定向等。你可以在Spring Gateway的配置中添加這些內置過濾器來滿足你的需求。以下是如何配置內置過濾器的一些示例:
鑒權過濾器:用于對請求進行身份驗證和授權,你可以使用AddRequestHeader
過濾器來添加認證信息到請求頭中。
spring: cloud: gateway: default-filters: - name: AddRequestHeader args: X-Request-Auth: some-auth-token
3. 重定向過濾器:用于將請求重定向到其他路徑或URL。你可以使用RedirectTo
過濾器來執(zhí)行重定向操作。
spring: cloud: gateway: routes: - id: my_redirect_route uri: http://example.com predicates: - Path=/redirect filters: - RedirectTo=302:http://new-location.com
4. 請求轉發(fā)過濾器:用于將請求轉發(fā)到其他服務或路徑。你可以使用ForwardTo
過濾器來執(zhí)行請求轉發(fā)。
spring: cloud: gateway: routes: - id: my_forward_route uri: http://example.com predicates: - Path=/forward filters: - ForwardTo=http://forward-service.com
5. 添加響應頭過濾器:用于在響應中添加額外的頭信息。你可以使用AddResponseHeader
過濾器來添加響應頭。
spring: cloud: gateway: default-filters: - name: AddResponseHeader args: X-Response-Header: some-value
這只是一些內置過濾器的示例,Spring Gateway提供了更多的內置過濾器,你可以根據你的需求在配置中使用它們。通過合理配置內置過濾器,你可以實現許多常見的網關功能,而無需自行編寫復雜的邏輯。
7.2 自定義Filter
要創(chuàng)建自定義過濾器(Custom Filter)來擴展Spring Cloud Gateway的功能,你需要遵循一些步驟。自定義過濾器可以用于執(zhí)行各種自定義操作,例如鑒權、日志記錄、修改請求和響應等。以下是創(chuàng)建自定義過濾器的一般步驟:
- 創(chuàng)建一個自定義過濾器類:首先,你需要創(chuàng)建一個Java類,實現
GatewayFilter
或GlobalFilter
接口。這兩個接口分別用于創(chuàng)建局部過濾器和全局過濾器。 - 局部過濾器 (
GatewayFilter
) 會應用于特定路由的請求。 - 全局過濾器 (
GlobalFilter
) 會應用于所有路由的請求。
下面我們以創(chuàng)建一個全局過濾器來展示如何創(chuàng)建自定義過濾器,要創(chuàng)建自定義的全局過濾器,你需要實現Spring Cloud Gateway的 GlobalFilter
接口。以下是創(chuàng)建一個簡單的全局自定義過濾器的步驟:
- 創(chuàng)建一個類,實現
GlobalFilter
接口。 - 在該類上添加
@Component
注解,以便Spring容器可以掃描并管理它。 - 實現
filter
方法,該方法包含你自定義過濾器的邏輯。
以下是一個示例自定義全局過濾器的代碼:
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class CustomGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 在請求處理之前執(zhí)行自定義邏輯 ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); // 在響應中添加自定義的HTTP頭 response.getHeaders().add("X-Custom-Header", "CustomHeaderValue"); // 修改請求或響應內容 ServerHttpRequest modifiedRequest = request.mutate() .header("X-Modified-Header", "ModifiedValue") .build(); ServerWebExchange modifiedExchange = exchange.mutate() .request(modifiedRequest) .build(); // 執(zhí)行鏈中的下一個過濾器或處理器 return chain.filter(modifiedExchange).then(Mono.fromRunnable(() -> { // 在請求處理完成后執(zhí)行自定義邏輯 // 這里可以對響應進行進一步處理 })); } @Override public int getOrder() { // 指定過濾器的執(zhí)行順序,可以是負數、零、正數,數字越小,執(zhí)行順序越靠前 return Ordered.HIGHEST_PRECEDENCE; } }
在上面的示例中,CustomGlobalFilter
是一個全局過濾器,它在請求處理前和請求處理后執(zhí)行自定義邏輯。你可以在 filter
方法中訪問請求、響應,修改它們的內容,添加自定義HTTP頭,以及執(zhí)行其他自定義邏輯。getOrder
方法用于指定過濾器的執(zhí)行順序,數字越小,執(zhí)行順序越靠前。
確保將 CustomGlobalFilter
類放在Spring Boot應用程序的類路徑下,Spring會自動識別并應用它。這樣,你的自定義全局過濾器就會在請求到達Spring Cloud Gateway時生效。
到此這篇關于Spring Gateway基礎教程的文章就介紹到這了,更多相關Spring Gateway基礎內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!