Spring?Gateway基礎(chǔ)教程
本文主要總結(jié)Spring Gateway的基礎(chǔ)用法,內(nèi)容包括網(wǎng)關(guān)、Spring Gateway工作流程、Spring Cloud Gateway搭建、路由配置方式、負(fù)載均衡實(shí)現(xiàn)、斷言工廠這幾個(gè)部分
1. 網(wǎng)關(guān)
1.1 網(wǎng)關(guān)介紹
在微服務(wù)架構(gòu)中,一個(gè)系統(tǒng)會被拆分為多個(gè)微服務(wù),那么作為客戶端如何去調(diào)用這些微服務(wù)呢?如果沒有網(wǎng)關(guān)的存在,我們只能在客戶端記錄每個(gè)微服務(wù)的地址,然后分別去調(diào)用,這樣會產(chǎn)生很多問題:
- 客戶端多次請求不同的微服務(wù),增加了客戶端代碼或配置編寫的復(fù)雜性
- 認(rèn)證復(fù),每個(gè)微服務(wù)需要獨(dú)立認(rèn)真
- 存在跨域問題,在一定場景下處理相對復(fù)雜
為了解決上述問題引入了網(wǎng)關(guān)概念:所謂的API網(wǎng)關(guān)就是指系統(tǒng)的統(tǒng)一入口,提供內(nèi)部服務(wù)的路由中轉(zhuǎn),為客戶端提供統(tǒng)一的服務(wù),一些與業(yè)務(wù)本身功能無關(guān)的公共邏輯可以在這里實(shí)現(xiàn),例如認(rèn)證、鑒權(quán)、監(jiān)控、路由轉(zhuǎn)發(fā)等。
1.2 網(wǎng)關(guān)對比
Zuul、Nginx+Lua 和 Spring Cloud Gateway 都可以用作API網(wǎng)關(guān),但它們在不同方面有一些不同之處,包括性能、擴(kuò)展性、功能和用途。以下是它們的主要比較:
- Zuul: 2. 性能:Zuul性能較低,特別是在處理大量并發(fā)請求時(shí)。它使用的是阻塞I/O,每個(gè)請求都會占用一個(gè)線程。 3. 擴(kuò)展性:Zuul的擴(kuò)展性相對較低。定制功能需要使用過濾器,這可能不夠靈活。 4. 功能:Zuul是Netflix OSS的一部分,提供基本的路由、負(fù)載均衡、重試等功能。然而,它的功能相對有限。 5. 用途:適合小規(guī)模的、非高并發(fā)的應(yīng)用,或者作為微服務(wù)架構(gòu)中的較早版本API網(wǎng)關(guān)。
- Nginx+Lua: 2. 性能:Nginx以其出色的性能而聞名。Nginx+Lua的組合可以在處理高并發(fā)請求時(shí)提供高性能,特別適合于需要低延遲的應(yīng)用。 3. 擴(kuò)展性:Nginx+Lua提供了強(qiáng)大的擴(kuò)展性。使用Lua腳本,你可以定制和擴(kuò)展其功能以適應(yīng)各種需求。 4. 功能:Nginx是一個(gè)功能強(qiáng)大的反向代理服務(wù)器,可以處理負(fù)載均衡、緩存、SSL終端、請求重寫、安全性等各種功能。 5. 用途:適合高并發(fā)的生產(chǎn)環(huán)境,特別是需要高性能和低延遲的應(yīng)用,一般用于一層網(wǎng)關(guān)。
- Spring Cloud Gateway: 2. 性能:Spring Cloud Gateway在性能方面表現(xiàn)不錯(cuò),它使用基于反應(yīng)性的編程模型,充分利用非阻塞I/O。 3. 擴(kuò)展性:Spring Cloud Gateway提供了很好的擴(kuò)展性,它是基于Spring Framework構(gòu)建的,因此可以與Spring生態(tài)系統(tǒng)的其他組件無縫集成。 4. 功能:Spring Cloud Gateway提供了路由、過濾器、限流、熔斷等功能,可以滿足大多數(shù)API網(wǎng)關(guān)的需求。 5. 用途:適合構(gòu)建微服務(wù)架構(gòu)中的API網(wǎng)關(guān),特別是在使用Spring Boot和Spring Cloud的應(yīng)用中。
1.3 Spring Gateway
Spring Cloud Gateway是一個(gè)用于構(gòu)建API網(wǎng)關(guān)的開源項(xiàng)目,它是Spring Cloud生態(tài)系統(tǒng)的一部分。API網(wǎng)關(guān)是微服務(wù)架構(gòu)中的關(guān)鍵組件之一,用于管理和路由傳入的請求,提供了一種集中化的訪問點(diǎn),可以實(shí)現(xiàn)諸如路由、負(fù)載均衡、身份驗(yàn)證、安全性、監(jiān)控、限流、重試等功能。Spring Cloud Gateway提供了一種現(xiàn)代、動(dòng)態(tài)、靈活且功能強(qiáng)大的方式來處理這些任務(wù)。
以下是Spring Cloud Gateway的一些主要特點(diǎn)和功能:
- 動(dòng)態(tài)路由:Spring Cloud Gateway允許你根據(jù)需要?jiǎng)討B(tài)配置路由,這意味著你可以在不停止網(wǎng)關(guān)的情況下修改路由規(guī)則。路由配置通常存儲在配置中心(如Spring Cloud Config)中,從而實(shí)現(xiàn)靈活的路由管理。
- 過濾器:Gateway提供了一組預(yù)定義的過濾器,用于請求和響應(yīng)的修改、校驗(yàn)、驗(yàn)證和監(jiān)控。你還可以編寫自定義過濾器以適應(yīng)特定需求。
- 負(fù)載均衡:Gateway集成了Spring Cloud LoadBalancer,可實(shí)現(xiàn)請求的負(fù)載均衡。你可以將請求路由到多個(gè)后端服務(wù)實(shí)例,實(shí)現(xiàn)高可用和擴(kuò)展性。
- 限流和熔斷:Spring Cloud Gateway支持通過集成Hystrix來實(shí)現(xiàn)限流和熔斷功能,以保護(hù)后端服務(wù)免受過多的請求壓力。
- 安全性:可以與Spring Security或其他身份驗(yàn)證和授權(quán)機(jī)制集成,實(shí)現(xiàn)安全的API訪問。
- 監(jiān)控和指標(biāo):Spring Cloud Gateway集成了Spring Boot Actuator,提供了各種有用的監(jiān)控和度量信息,可以使用Micrometer將這些信息導(dǎo)出到多個(gè)監(jiān)控系統(tǒng)。
- WebSockets支持:Gateway支持WebSockets,因此可以處理實(shí)時(shí)通信的需求。
- HTTP/2支持:可以通過配置啟用HTTP/2協(xié)議,以提高性能。
- 自定義路由規(guī)則:除了使用配置外,你還可以編寫自定義的路由規(guī)則,以實(shí)現(xiàn)更復(fù)雜的路由需求。
Spring Cloud Gateway是建立在Spring Framework和Spring Boot的基礎(chǔ)上的,因此與Spring生態(tài)系統(tǒng)的其他組件無縫集成。它為構(gòu)建微服務(wù)架構(gòu)中的API網(wǎng)關(guān)提供了靈活、高性能和現(xiàn)代的解決方案。
特點(diǎn):
- 性能強(qiáng)大:是Zuul性能的1.6倍
- 功能強(qiáng)大:內(nèi)置了很多實(shí)用功能,如轉(zhuǎn)發(fā)、監(jiān)控、限流等
- 設(shè)計(jì)優(yōu)雅,易于拓展
1.4 核心概念
在Spring Gateway中:
- 路由(Route):路由是網(wǎng)關(guān)的基本構(gòu)建單元,包括以下屬性:
- ID(標(biāo)識):路由的唯一標(biāo)識。
- URI(目標(biāo)URI):定義路由請求將被轉(zhuǎn)發(fā)到的目標(biāo)URI。
- 斷言(Predicates):一組謂詞,用于匹配HTTP請求的屬性,如路徑、主機(jī)、標(biāo)頭等。
- 過濾器(Filters):一組過濾器,用于在請求到達(dá)目標(biāo)URI之前或響應(yīng)返回之前對請求和響應(yīng)進(jìn)行修改。
- 舉例:定義一個(gè)路由,將匹配
/example
路徑的請求,將其轉(zhuǎn)發(fā)到http://example.com
:
id: example_route uri: example.com predicates:
- Path=/example
斷言(Predicate):謂詞是用于匹配HTTP請求的條件。謂詞可以基于請求的各種屬性,如路徑、主機(jī)、標(biāo)頭等。例如,Path
謂詞可以匹配請求路徑。
舉例:定義一個(gè)謂詞,要求請求路徑必須以/api
開頭:
predicates:
- Path=/api/**
- 過濾器(Filter):過濾器是網(wǎng)關(guān)中的處理器,它們可以在請求到達(dá)目標(biāo)URI之前或響應(yīng)返回之前對請求和響應(yīng)進(jìn)行修改。過濾器可以用于添加標(biāo)頭、修改請求體、記錄日志等操作。
舉例:定義一個(gè)過濾器,向響應(yīng)標(biāo)頭中添加X-Custom-Header
標(biāo)頭:
filters:
- AddResponseHeader=X-Custom-Header, Gateway
這些組件一起構(gòu)成了Spring Gateway的核心功能,允許您定義路由規(guī)則、請求匹配條件以及請求和響應(yīng)的處理操作。
1.6 總結(jié)
SpringCloud Gateway使用的是WebFlux中的reactor-netty響應(yīng)式編程組件,底層使用Netty通訊框架。
2. Spring Gateway工作流程
2.1 官網(wǎng)上的核心工作流程
核心流程圖如下:
核心流程:
- 客戶端(Gateway Client)向 Spring Cloud Gateway發(fā)送請求。
- 如果Gateway Handler Mapping確定請求與路由匹配,則將其發(fā)送到Gateway Web Handler處理程序。
- 接著處理程序通過特定于請求的Filter鏈過濾請求。Filter被虛線分隔的原因是Filter可以在發(fā)送代理請求之前(pre)和之后(post)運(yùn)行邏輯。執(zhí)行所有pre過濾器邏輯,然后進(jìn)行代理請求,發(fā)送代理請求之后,運(yùn)行“post”過濾器邏輯
- 過濾器作用:
- Filter在pre類型的過濾器可以做參數(shù)校驗(yàn),權(quán)限校驗(yàn)、流量監(jiān)控、日志輸出和協(xié)議轉(zhuǎn)換等。
- Filter在Post類型的過濾器可以做響應(yīng)內(nèi)容、響應(yīng)頭的修改、日志輸出和流量監(jiān)控等
核心點(diǎn):
- Route(路由):路由是構(gòu)建網(wǎng)關(guān)的基礎(chǔ)模塊兒,它由ID,目標(biāo)URI,包括一系列的斷言喝過濾器組成,如果斷言為True則匹配該路由。
- Predicate(斷言):開發(fā)人員可以匹配http請求中的所有內(nèi)容(如:請求頭或請求參數(shù)),請求與斷言匹配則進(jìn)行路由。
- Filter(過濾):指Spring框架中GatewayWayFilter的實(shí)例,使用過濾器可以在請求被路由前或者之后對請求進(jìn)行修改。
- 三個(gè)核心點(diǎn)連起來:當(dāng)用戶的請求到達(dá)Gateway,Gateway會通過一些匹配條件,定位到真正的服務(wù)節(jié)點(diǎn),并在這個(gè)轉(zhuǎn)發(fā)過程前后,進(jìn)行一些細(xì)化控制。其中Predicate就是我們的匹配條件,F(xiàn)ilter可以理解為一個(gè)過濾器,有了這兩點(diǎn),再加上目標(biāo)URI就可以實(shí)現(xiàn)一個(gè)具體路由了
2.2 Spring Gateway執(zhí)行流程
如上圖所示,當(dāng)使用Spring Gateway處理請求時(shí),它經(jīng)歷以下流程:
- Client向Gateway Server發(fā)送請求: 客戶端(例如瀏覽器、移動(dòng)應(yīng)用或其他服務(wù))發(fā)送HTTP請求到Spring Gateway服務(wù)器,這是請求的起始點(diǎn)。
- 請求會被HttpWebHandlerAdapter提取組裝成網(wǎng)關(guān)上下文:
- 請求進(jìn)入Spring Gateway后,首先被HttpWebHandlerAdapter處理。這個(gè)組件負(fù)責(zé)提取HTTP請求信息,并將其組裝成網(wǎng)關(guān)上下文對象,其中包括請求的各種信息,如HTTP頭、請求參數(shù)等。
- 網(wǎng)關(guān)上下文會傳遞到DispatcherHandler:
- 組裝好的網(wǎng)關(guān)上下文被傳遞到DispatcherHandler,它是Spring Gateway的核心處理器。DispatcherHandler的任務(wù)是將請求分發(fā)到合適的處理程序。
- RoutePredicateHandlerMapping負(fù)責(zé)路由查找,并根據(jù)路由斷言判斷路由是否可用:
- RoutePredicateHandlerMapping負(fù)責(zé)路由查找,它將根據(jù)網(wǎng)關(guān)上下文中的信息選擇適當(dāng)?shù)穆酚?。每個(gè)路由都包括一個(gè)或多個(gè)路由斷言,這些斷言是用來判斷該路由是否適用于當(dāng)前請求的條件。
- 如果斷言成功,由FilteringWebHandler創(chuàng)建過濾器鏈并調(diào)用:
如果路由斷言成功,表示當(dāng)前請求匹配了某個(gè)路由規(guī)則。此時(shí),將會由FilteringWebHandler創(chuàng)建一個(gè)過濾器鏈,并按照鏈的順序調(diào)用這些過濾器。過濾器可以在請求到達(dá)后端服務(wù)之前或響應(yīng)返回給客戶端之前對請求進(jìn)行修改、驗(yàn)證或記錄日志等操作。
這個(gè)流程允許Spring Gateway進(jìn)行請求的路由和過濾,以實(shí)現(xiàn)對請求的控制和處理。通過配置不同的路由規(guī)則和過濾器,可以根據(jù)請求的性質(zhì)來決定如何處理請求,例如路由到不同的后端服務(wù)、添加安全性措施或改變請求和響應(yīng)的內(nèi)容。
總結(jié)
Gateway的核心流程就是:路由轉(zhuǎn)發(fā)+執(zhí)行過濾器鏈
3. Spring Cloud Gateway搭建
3.1 Gateway搭建
搭建一個(gè)cloud-alibaba-gateway項(xiàng)目,因?yàn)槭褂昧藄pring cloud 所以需要注意版本間的匹配,這里可以通過阿里的云原生腳手架去獲取適合的版本:[start.aliyun.com/]
搭建Spring Gateway項(xiàng)目之前需要一些前置搭建微服務(wù)注冊中心(Nacos,Consul,Eureka等),這里我使用Nacos進(jìn)行演示,Nacos的搭建流程可以參考:[http://www.dbjr.com.cn/article/184641.htm]
該案例的完整代碼可以在gitee項(xiàng)目中獲取:[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一定要?jiǎng)h除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 #服務(wù)id,對應(yīng)nacos中注冊的服務(wù)名 uri: http://localhost:9003/nacos-provider #訪問的uri地址 predicates: - Path=/ts/** #斷言,對請求進(jìn)行匹配,只有包含/ts的路徑才能通過斷言
controller (微服務(wù)cloud-alibaba-provider-9003)
這里我們搭建了另外一個(gè)微服務(wù)cloud-alibaba-provider-9003作為服務(wù)的提供者來驗(yàn)證網(wǎng)關(guān)是否生效,這個(gè)微服務(wù)的邏輯非常簡單,使用HashMap模擬一個(gè)一個(gè)數(shù)據(jù)庫的獲取操作如下:
@RequestMapping("/ts") @RestController public class DataController { @Value("${server.port}") String serverPort; public static HashMap<Long,String> hashMap = new HashMap<>(); static { hashMap.put(1l,"鼠標(biāo)"); hashMap.put(2l,"鍵盤"); hashMap.put(3l,"耳機(jī)"); } @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]
如下圖所示,我們通過微服務(wù)提供者的url對服務(wù)進(jìn)行訪問,而是通過gateway網(wǎng)關(guān)的路徑對微服務(wù)進(jìn)行訪問成功了,就說明我們的網(wǎng)關(guān)搭建成功了。
3.2 總結(jié)
這里以一個(gè)簡單的例子展示了Spring Gateway網(wǎng)關(guān)的基礎(chǔ)搭建和測試過程,相關(guān)的服務(wù)搭建都是在本地完成的,完整的代碼請參考我的gitee項(xiàng)目:[gitee.com/lei-qinghua…]
4. Gateway路由配置方式
在第三節(jié)中我們用yml文件對Gateway的路由方式進(jìn)行了配置,實(shí)際上Gateway還可以通過Java代碼的方式來進(jìn)行路由配置。
4.1 Gateway Config
通過@Bean 注入一個(gè)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實(shí)現(xiàn)負(fù)載均衡
5.1 什么是負(fù)載均衡
微服務(wù)系統(tǒng)的負(fù)載均衡是一種機(jī)制,用于在微服務(wù)架構(gòu)中均勻分配網(wǎng)絡(luò)請求和流量到不同的微服務(wù)實(shí)例,以確保各個(gè)服務(wù)的資源充分利用,提高系統(tǒng)的性能、可用性和穩(wěn)定性。在微服務(wù)架構(gòu)中,通常存在多個(gè)相同或相似的微服務(wù)實(shí)例,每個(gè)實(shí)例都提供相同的服務(wù)接口,但可能運(yùn)行在不同的主機(jī)或容器上。
以下是微服務(wù)系統(tǒng)中負(fù)載均衡的一些關(guān)鍵概念和特點(diǎn):
- 服務(wù)實(shí)例均衡分配:微服務(wù)負(fù)載均衡確保來自客戶端的請求均勻分布到不同的服務(wù)實(shí)例上,以防止某些實(shí)例過載而其他實(shí)例處于空閑狀態(tài)。
- 多種負(fù)載均衡策略:微服務(wù)負(fù)載均衡可以采用不同的策略,如輪詢、隨機(jī)、最少連接等,以選擇目標(biāo)服務(wù)實(shí)例。每種策略有其用途,根據(jù)具體情況選擇合適的策略。
- 健康檢查:負(fù)載均衡器定期檢查每個(gè)服務(wù)實(shí)例的健康狀態(tài),以確定哪些實(shí)例可以接收請求。如果某個(gè)實(shí)例不健康或不可用,負(fù)載均衡器將停止將請求路由到該實(shí)例。
- 自動(dòng)擴(kuò)展:微服務(wù)系統(tǒng)的負(fù)載均衡應(yīng)該支持自動(dòng)擴(kuò)展。當(dāng)系統(tǒng)負(fù)載增加時(shí),可以自動(dòng)添加新的服務(wù)實(shí)例以處理更多請求。這有助于應(yīng)對流量波動(dòng)和系統(tǒng)的橫向擴(kuò)展。
- 故障轉(zhuǎn)移:如果某個(gè)服務(wù)實(shí)例出現(xiàn)故障,負(fù)載均衡器應(yīng)該自動(dòng)將流量轉(zhuǎn)移到其他健康的實(shí)例,以確保系統(tǒng)的可用性。
- 會話粘附:在某些情況下,需要確保同一客戶端的多個(gè)請求被路由到同一服務(wù)實(shí)例,以維護(hù)會話一致性。這稱為會話粘附,一些負(fù)載均衡器支持此功能。
微服務(wù)系統(tǒng)的負(fù)載均衡是確保整個(gè)系統(tǒng)運(yùn)行順暢的重要組成部分。它有助于避免單點(diǎn)故障,提高系統(tǒng)的可用性,并允許系統(tǒng)根據(jù)需求自動(dòng)擴(kuò)展。選擇適當(dāng)?shù)呢?fù)載均衡策略和工具對于構(gòu)建穩(wěn)健的微服務(wù)系統(tǒng)至關(guān)重要。
5.2 自動(dòng)負(fù)載均衡
Gateway還提供了和Zuul類似的自動(dòng)路由規(guī)則,具體配置如下:
- gateway.discovery.locator.enabled = true 這個(gè)配置默認(rèn)為false,但是如果設(shè)置為true就是開啟了通過serviceID轉(zhuǎn)發(fā)到具體的服務(wù)實(shí)例。
- 配置好之后,可以直接通過服務(wù)名稱來進(jìn)行訪問Nacos中注冊的服務(wù)和對應(yīng)接口。
- Gateway在開啟了自動(dòng)路由之后還自帶負(fù)載均衡功能。
server: port: 9999 spring: application: name: cloud-gateway-service cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true # 開啟自動(dòng)路由功能,根據(jù)服務(wù)名自動(dòng)創(chuàng)建routes
測試:[http://localhost:9999/nacos-provider/info/1]
我們直接通過spring gateway的服務(wù)地址和服務(wù)提供者nacos-provider的服務(wù)名組成的url地址,就可以以負(fù)載均衡的方式訪問nacos-provider的服務(wù)。
5.3 手動(dòng)負(fù)載均衡
自動(dòng)負(fù)載均衡存在一個(gè)問題就是需要暴露每一個(gè)服務(wù)的服務(wù)名稱,因此可以采用手動(dòng)負(fù)載均衡的方式來避免暴露微服務(wù)的服務(wù)名稱。
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 # 開啟負(fù)載均衡,服務(wù)名稱為nacos-provider predicates: # 斷言,放開所有路徑 - Path=/**
- lb:// 代表開啟負(fù)載均衡
- 測試:[http://localhost:9999/info/1]
6. Gateway斷言Predicate
Gateway斷言可以理解為當(dāng)滿足條件后才會進(jìn)行轉(zhuǎn)發(fā),總結(jié)就是Predicate就是為了實(shí)現(xiàn)一組匹配規(guī)則,讓請求過來找到相應(yīng)的Route進(jìn)行處理。
6.1 斷言種類
Spring Cloud Gateway支持多種路由斷言(Route Predicates)類型,用于匹配和路由HTTP請求。以下是一些常見的路由斷言類型:
Path Route Predicate(路徑匹配):根據(jù)請求的路徑進(jìn)行匹配。
predicates:
Path=/api/**
這將匹配所有以/api/
開頭的路徑。
Host Route Predicate(主機(jī)匹配):根據(jù)請求的主機(jī)名進(jìn)行匹配。
predicates:
Host=example.com
這將匹配主機(jī)名為example.com
的請求。
Method Route Predicate(HTTP方法匹配):根據(jù)HTTP請求方法進(jìn)行匹配。
predicates:
Method=GET
這將匹配HTTP GET請求。
Header Route Predicate(請求頭匹配):根據(jù)請求頭信息進(jìn)行匹配。
predicates:
Header=Authorization, Bearer .+
這將匹配包含Authorization
頭且值以Bearer開頭的請求。
Query Route Predicate(查詢參數(shù)匹配):根據(jù)請求的查詢參數(shù)進(jìn)行匹配。
predicates:
Query=name, john
這將匹配包含name=john
的查詢參數(shù)的請求。
Cookie Route Predicate(Cookie匹配):根據(jù)請求的Cookie信息進(jìn)行匹配。
predicates:
Cookie=sessionId, .+
這將匹配包含名為sessionId
的Cookie的請求。
Combining Predicates(組合匹配):你可以組合多個(gè)路由斷言來創(chuàng)建更復(fù)雜的匹配條件。
- predicates:
- Path=/api/**Host=example.com
這將匹配主機(jī)為example.com
且路徑以/api/
開頭的請求。
這些路由斷言允許你根據(jù)請求的不同屬性(如路徑、主機(jī)、請求頭、HTTP方法等)進(jìn)行匹配和路由,從而更靈活地控制請求的路由和處理。你可以在Spring Cloud Gateway的路由配置中定義這些路由斷言,以滿足你的具體需求。
7. Gateway的Filter
路由過濾器允許以某種方式修改傳入的http請求或傳出的HTTP響應(yīng),路由過濾器的范圍是特定的路由Spring Cloud Gateway包含許多內(nèi)置的Gateway Filter工廠。
7.1 內(nèi)置Filter
7.1.1 內(nèi)置過濾器分類
Gateway內(nèi)置的Filter生命周期分為兩種:pre(業(yè)務(wù)邏輯之前)、post(業(yè)務(wù)邏輯之后)
Gateway本身自帶的Filter分為2種:GateWayFilter(單一)、GlobalFilter(全局)
Spring Cloud Gateway提供了多個(gè)內(nèi)置的過濾器(Filters),這些過濾器允許你在請求和響應(yīng)的生命周期中執(zhí)行各種操作,例如請求路由、修改請求和響應(yīng)、增加頭信息等。以下是一些常見的內(nèi)置過濾器:
- Forward Routing Filter:用于路由請求到后端服務(wù)。
- LoadBalancerClient Filter:通過LoadBalancerClient執(zhí)行負(fù)載均衡請求。
- AddRequestHeader Filter:在請求中添加頭信息。
- AddRequestParameter Filter:在請求中添加查詢參數(shù)。
- RewritePath Filter:重寫請求路徑,用于修改請求的路徑。
- SetStatus Filter:設(shè)置HTTP響應(yīng)狀態(tài)碼。
- AddResponseHeader Filter:在響應(yīng)中添加頭信息。
- Hystrix Filter:用于Hystrix斷路器的支持。
- WebSockets Filter:用于WebSocket代理。
- ModifyResponseBody Filter:修改響應(yīng)體內(nèi)容。
- PreserveHostHeader Filter:保留原始主機(jī)頭信息。
- RequestRateLimiter Filter:實(shí)現(xiàn)請求速率限制。
這些內(nèi)置過濾器可以通過Spring Cloud Gateway的路由配置文件進(jìn)行配置,從而對請求和響應(yīng)進(jìn)行自定義處理。你可以根據(jù)具體需求組合和配置這些過濾器,以滿足你的應(yīng)用程序的需求。此外,你也可以編寫自定義過濾器來執(zhí)行更高度定制的操作。過濾器在Gateway中扮演了非常重要的角色,幫助你實(shí)現(xiàn)請求的路由和處理邏輯。
7.1.2 內(nèi)置過濾器配置
Spring Gateway提供了許多內(nèi)置的過濾器,用于執(zhí)行常見的網(wǎng)關(guān)任務(wù),例如鑒權(quán)、請求轉(zhuǎn)發(fā)、重定向等。你可以在Spring Gateway的配置中添加這些內(nèi)置過濾器來滿足你的需求。以下是如何配置內(nèi)置過濾器的一些示例:
鑒權(quán)過濾器:用于對請求進(jìn)行身份驗(yàn)證和授權(quán),你可以使用AddRequestHeader
過濾器來添加認(rèn)證信息到請求頭中。
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. 請求轉(zhuǎn)發(fā)過濾器:用于將請求轉(zhuǎn)發(fā)到其他服務(wù)或路徑。你可以使用ForwardTo
過濾器來執(zhí)行請求轉(zhuǎn)發(fā)。
spring: cloud: gateway: routes: - id: my_forward_route uri: http://example.com predicates: - Path=/forward filters: - ForwardTo=http://forward-service.com
5. 添加響應(yīng)頭過濾器:用于在響應(yīng)中添加額外的頭信息。你可以使用AddResponseHeader
過濾器來添加響應(yīng)頭。
spring: cloud: gateway: default-filters: - name: AddResponseHeader args: X-Response-Header: some-value
這只是一些內(nèi)置過濾器的示例,Spring Gateway提供了更多的內(nèi)置過濾器,你可以根據(jù)你的需求在配置中使用它們。通過合理配置內(nèi)置過濾器,你可以實(shí)現(xiàn)許多常見的網(wǎng)關(guān)功能,而無需自行編寫復(fù)雜的邏輯。
7.2 自定義Filter
要?jiǎng)?chuàng)建自定義過濾器(Custom Filter)來擴(kuò)展Spring Cloud Gateway的功能,你需要遵循一些步驟。自定義過濾器可以用于執(zhí)行各種自定義操作,例如鑒權(quán)、日志記錄、修改請求和響應(yīng)等。以下是創(chuàng)建自定義過濾器的一般步驟:
- 創(chuàng)建一個(gè)自定義過濾器類:首先,你需要?jiǎng)?chuàng)建一個(gè)Java類,實(shí)現(xiàn)
GatewayFilter
或GlobalFilter
接口。這兩個(gè)接口分別用于創(chuàng)建局部過濾器和全局過濾器。 - 局部過濾器 (
GatewayFilter
) 會應(yīng)用于特定路由的請求。 - 全局過濾器 (
GlobalFilter
) 會應(yīng)用于所有路由的請求。
下面我們以創(chuàng)建一個(gè)全局過濾器來展示如何創(chuàng)建自定義過濾器,要?jiǎng)?chuàng)建自定義的全局過濾器,你需要實(shí)現(xiàn)Spring Cloud Gateway的 GlobalFilter
接口。以下是創(chuàng)建一個(gè)簡單的全局自定義過濾器的步驟:
- 創(chuàng)建一個(gè)類,實(shí)現(xiàn)
GlobalFilter
接口。 - 在該類上添加
@Component
注解,以便Spring容器可以掃描并管理它。 - 實(shí)現(xiàn)
filter
方法,該方法包含你自定義過濾器的邏輯。
以下是一個(gè)示例自定義全局過濾器的代碼:
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(); // 在響應(yīng)中添加自定義的HTTP頭 response.getHeaders().add("X-Custom-Header", "CustomHeaderValue"); // 修改請求或響應(yīng)內(nèi)容 ServerHttpRequest modifiedRequest = request.mutate() .header("X-Modified-Header", "ModifiedValue") .build(); ServerWebExchange modifiedExchange = exchange.mutate() .request(modifiedRequest) .build(); // 執(zhí)行鏈中的下一個(gè)過濾器或處理器 return chain.filter(modifiedExchange).then(Mono.fromRunnable(() -> { // 在請求處理完成后執(zhí)行自定義邏輯 // 這里可以對響應(yīng)進(jìn)行進(jìn)一步處理 })); } @Override public int getOrder() { // 指定過濾器的執(zhí)行順序,可以是負(fù)數(shù)、零、正數(shù),數(shù)字越小,執(zhí)行順序越靠前 return Ordered.HIGHEST_PRECEDENCE; } }
在上面的示例中,CustomGlobalFilter
是一個(gè)全局過濾器,它在請求處理前和請求處理后執(zhí)行自定義邏輯。你可以在 filter
方法中訪問請求、響應(yīng),修改它們的內(nèi)容,添加自定義HTTP頭,以及執(zhí)行其他自定義邏輯。getOrder
方法用于指定過濾器的執(zhí)行順序,數(shù)字越小,執(zhí)行順序越靠前。
確保將 CustomGlobalFilter
類放在Spring Boot應(yīng)用程序的類路徑下,Spring會自動(dòng)識別并應(yīng)用它。這樣,你的自定義全局過濾器就會在請求到達(dá)Spring Cloud Gateway時(shí)生效。
到此這篇關(guān)于Spring Gateway基礎(chǔ)教程的文章就介紹到這了,更多相關(guān)Spring Gateway基礎(chǔ)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入淺出講解Spring框架中依賴注入與控制反轉(zhuǎn)及應(yīng)用
依賴注入(Dependency?Injection)和控制反轉(zhuǎn)(Inversion?of?Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在?傳統(tǒng)的程序設(shè)計(jì)過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實(shí)例2022-03-03Java解決浮點(diǎn)數(shù)計(jì)算不精確問題的方法詳解
在 Java 中,浮點(diǎn)數(shù)計(jì)算不精確問題指的是使用浮點(diǎn)數(shù)進(jìn)行運(yùn)算時(shí),由于浮點(diǎn)數(shù)的內(nèi)部表示方式和十進(jìn)制數(shù)的表示方式存在差異,導(dǎo)致計(jì)算結(jié)果可能出現(xiàn)誤差,本文就給大家介紹一下Java如何解決浮點(diǎn)數(shù)計(jì)算不精確問題,需要的朋友可以參考下2023-09-09java設(shè)計(jì)模式之外觀模式(Facade)
這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式之外觀模式Facade的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01JAVA實(shí)現(xiàn)PDF轉(zhuǎn)HTML文檔的示例代碼
本文是基于PDF文檔轉(zhuǎn)PNG圖片,然后進(jìn)行圖片拼接,拼接后的圖片轉(zhuǎn)為base64字符串,然后拼接html文檔寫入html文件實(shí)現(xiàn)PDF文檔轉(zhuǎn)HTML文檔,感興趣的可以了解一下2021-05-05IDEA導(dǎo)入Eclipse項(xiàng)目的方法步驟(圖文教程)
這篇文章主要介紹了IDEA導(dǎo)入Eclipse項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03