目錄
一、Spring Cloud Gateway
1、網(wǎng)關(guān)介紹
2、GateWay
3、GateWay項目搭建
4、GateWay配置路由的兩種方式
4.1、YML配置
4.2、配置類
5、GateWay實現(xiàn)負載均衡
5.1、自動負載均衡
5.2、手動負載均衡
6、GateWay斷言Predicate
7、GateWay的Filter
一、Spring Cloud Gateway
1、網(wǎng)關(guān)介紹
????????在微服務架構(gòu)中,一個系統(tǒng)會被拆分為很多個微服務。那么作為客戶端要如何去調(diào)用這么多的微服務呢?如果沒有網(wǎng)關(guān)的存在,我們只能在客戶端記錄每個微服務的地址,然后分別去調(diào)用。這樣的話會產(chǎn)生很多問題,例如:
- 客戶端多次請求不同的微服務,增加客戶端代碼或配置編寫的復雜性
- 認證復雜,每個微服務都有獨立認證
- 存在跨域請求,在一定場景下處理相對復雜
為解決上面的問題所以引入了網(wǎng)關(guān)的概念:所謂的API網(wǎng)關(guān),就是指系統(tǒng)的統(tǒng)一入口,提供內(nèi)部服務的路由中轉(zhuǎn),為客戶端提供統(tǒng)一服務,一些與業(yè)務本身功能無關(guān)的公共邏輯可以在這里實現(xiàn),諸如認證、鑒權(quán)、監(jiān)控、路由轉(zhuǎn)發(fā)等。
系統(tǒng)架構(gòu)圖
網(wǎng)關(guān)對比
Zuul 1.x:Netflix開源的網(wǎng)關(guān),基于Servlet框架構(gòu)建,功能豐富,使用JAVA開發(fā),易于二次開發(fā) 問題:即一個線程處理一次連接請求,這種方式在內(nèi)部延遲嚴重、設備故障較多情況下會引起存活的連接增多和線程增加的情況發(fā)生。
Zuul 2.x:Zuul2 采用了Netty實現(xiàn)異步非阻塞編程模型,每個 CPU 核一個線程,處理所有的請求和響應,請求和響應的生命周期是通過事件和回調(diào)來處理的,這種方式減少了線程數(shù)量,因此開銷較小。
GateWay:Spring公司為了替換Zuul而開發(fā)的網(wǎng)關(guān)服務,底層為Netty,將在下面具體介紹。
Nginx+lua:使用nginx的反向代理和負載均衡可實現(xiàn)對api服務器的負載均衡及高可用,lua是一種腳本語言,可以來編寫一些簡單的邏輯, nginx支持lua腳本,問題在于:無法融入到微服務架構(gòu)中
Kong:基于Nginx+Lua開發(fā),性能高,穩(wěn)定,有多個可用的插件(限流、鑒權(quán)等等)可以開箱即用。 問題:只支持Http協(xié)議;二次開發(fā),自由擴展困難;提供管理API,缺乏更易用的管控、配置方式。
2、GateWay
Spring Cloud Gateway 基于Spring Boot 2.x、Spring WebFlux和Project Reactor,它旨在為微服務架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式。它的目標是替代Netflix Zuul,其不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全,監(jiān)控和限流。
Spring Cloud Gateway官網(wǎng)地址
特點:
1. 性能強勁:是Zuul的1.6倍
2. 功能強大:內(nèi)置了很多實用的功能,例如轉(zhuǎn)發(fā)、監(jiān)控、限流等
3. 設計優(yōu)雅,容易擴展
基本概念:
路由(Route) 是 gateway 中最基本的組件之一,表示一個具體的路由信息載體。主要定義了下面的幾個信息:
- ?id:路由標識、區(qū)別于其他route
- uri:路由指向的目的地uri,即客戶端請求最終被轉(zhuǎn)發(fā)到的微服務
- order:用于多個route之間的排序,數(shù)值越小排序越靠前,匹配優(yōu)先級越高
- predicate:斷言的作用是進行條件判斷,只有斷言都返回真,才會真正的執(zhí)行路由?
- filter:過濾器用于修改請求和響應信息
執(zhí)行流程:
1. Gateway Client向Gateway Server發(fā)送請求
2. 請求首先會被HttpWebHandlerAdapter進行提取組裝成網(wǎng)關(guān)上下文
3. 然后網(wǎng)關(guān)的上下文會傳遞到DispatcherHandler,它負責將請求分發(fā)給RoutePredicateHandlerMapping
4. RoutePredicateHandlerMapping負責路由查找,并根據(jù)路由斷言判斷路由是否可用
5. 如果過斷言成功,由FilteringWebHandler創(chuàng)建過濾器鏈并調(diào)用
6. 請求會一次經(jīng)過PreFilter--微服務--PostFilter的方法,最終返回響應
核心流程圖
客戶端向 Spring Cloud Gateway 發(fā)出請求。如果Gateway Handler Mapping確定請求與路由匹配,則將其發(fā)送到Gateway Web Handler 處理程序。此處理程序通過特定于請求的Fliter鏈運行請求。Fliter被虛線分隔的原因是Fliter可以在發(fā)送代理請求之前(pre)和之后(post)運行邏輯。執(zhí)行所有pre過濾器邏輯。然后進行代理請求。發(fā)出代理請求后,將運行“post”過濾器邏輯。
過濾器作用:
- Filter在pre類型的過濾器可以做參數(shù)效驗、權(quán)限效驗、流量監(jiān)控、日志輸出、協(xié)議轉(zhuǎn)換等。
- Filter在post類型的過濾器可以做響應內(nèi)容、響應頭的修改、日志輸出、流量監(jiān)控等
- 這兩種類型的過濾器有著非常重要的作用
GateWay的內(nèi)部有三個核心點
Route(路由)
路由是構(gòu)建網(wǎng)關(guān)的基礎模塊,它由ID,目標URI,包括一些列的斷言和過濾器組成,如果斷言為true則匹配該路由
Predicate(斷言)
參考的是Java8的java.util.function.Predicate,開發(fā)人員可以匹配HTTP請求中的所有內(nèi)容(例如請求頭或請求參數(shù)),請求與斷言匹配則進行路由
Filter(過濾)
指的是Spring框架中GateWayFilter的實例,使用過濾器,可以在請求被路由前或者之后對請求進行修改。
三個核心點連起來:
當用戶發(fā)出請求到達GateWay,GateWay會通過一些匹配條件,定位到真正的服務節(jié)點,并在這個轉(zhuǎn)發(fā)過程前后,進行一些及細化控制。其中Predicate就是我們匹配的條件,而Filter可以理解為一個攔截器,有了這兩個點,再加上目標URI,就可以實現(xiàn)一個具體的路由了。
GateWay核心的流程就是:路由轉(zhuǎn)發(fā)+執(zhí)行過濾器鏈
SpringCloud GateWay使用的是Webflux中的reactor-netty響應式編程組件,底層使用了Netty通訊框架。
3、GateWay項目搭建
搭建一個GateWay項目cloudalibaba-gateway-9999
版本對應地址
這里使用SpringBoot2.2.6的版本所以配合的是SpringCloud的Hoxton.SR5版本
注意:引入GateWay一定要刪除spring-boot-starter-web依賴,否則會有沖突無法啟動
父級項目引入
<!--spring cloud Hoxton.SR5-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
子級項目,因為GateWay也需要注冊進Nacos,所以也需要Nacos的依賴
<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-gateway</artifactId>
</dependency>
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 #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: http://localhost:9003/nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/** # 斷言,路徑相匹配進行路由
9003、9004追加控制器
@RestController
@RequestMapping("/lwz")//路由路徑
public class GateWayController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/get")
public String getServerPort(){
return "GateWay-1:"+serverPort;
}
}
測試:
啟動Nacos、9003和9999網(wǎng)關(guān),通過網(wǎng)關(guān)訪問9003的/lwz/get接口同時查看Nacos控制臺
http://localhost:9999/lwz/get
Nacos控制臺成功注冊GateWay網(wǎng)關(guān)
?
4、GateWay配置路由的兩種方式
4.1、YML配置
通過上面案例在YML中配置
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟注冊中心路由功能
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: http://localhost:9003/nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/** # 斷言,路徑相匹配進行路由
4.2、配置類
通過配置類@Configuration,通過@Bean注入一個RouteLocator方式
Spring Cloud Gateway官網(wǎng)案例
具體操作
創(chuàng)建配置類GateWayConfig,內(nèi)容和上面yml配置一樣
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){
// 構(gòu)建多個路由routes
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
// 具體路由地址
routes.route("path_lwz",r -> r.path("/lwz/**").uri("http://localhost:9003/nacos-provider")).build();
// 返回所有路由規(guī)則
return routes.build();
}
}
測試:
把9003 yml路由配置去掉,開始測試
啟動Nacos、9003和9999網(wǎng)關(guān),通過網(wǎng)關(guān)訪問9003的/lwz/get接口
5、GateWay實現(xiàn)負載均衡
此時把配置類注釋掉使用yml操作
5.1、自動負載均衡
1. gateway.discovery.locator.enabled: true #開啟自動路由功能
2. routes中的uri其實最后是不需要服務名稱的,這個位置其實只需要指定的localhost:9003即可
修改配置uri中的/nacos-provider去掉
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 #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: http://localhost:9003 # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/** # 斷言,路徑相匹配進行路由
啟動Nacos、9003和9999網(wǎng)關(guān),通過網(wǎng)關(guān)訪問9003的/lwz/get接口
依然是可以訪問
自動路由規(guī)則
GateWay還提供了和Zuul類似的自動路由規(guī)則,具體配置如下:
1. discovery.locator.enabled: true #這個配置默認為false,但是如果為true,就是開啟了通過serviceId轉(zhuǎn)發(fā)到具體的服務實例?!發(fā)ocalhost:9999/ServiceID/lwz/**”
2. 在配置好這些以后,我們可以直接通過服務名稱來進行訪問Nacos中注冊的服務和對應的接口
3. 這個位置我們?yōu)榱藴y試可以啟動2個微服務9003、9004
4. GateWay在開啟了自動路由以后,還自帶負載均衡
測試:
9004和9003保持一致
啟動Nacos、9003和9004和9999網(wǎng)關(guān)
http://localhost:9999/nacos-provider/lwz/get
在以上的配置中,其實是有問題的,問題在于當前的服務名稱暴露,并且太過于靈活,那么如果想解決的話,其實我們可以進行手動配置。
5.2、手動負載均衡
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
lb://代表開啟負載均衡
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān)
6、GateWay斷言Predicate
每一個Predicate的使用,可以理解為:當滿足條件后才會進行轉(zhuǎn)發(fā),如果是多個,那就是滿足所有條件才會轉(zhuǎn)發(fā)。
斷言種類
1. After:匹配在指定日期時間之后發(fā)生的請求。
2. Before:匹配在指定日期之前發(fā)生的請求。
3. Between:需要指定兩個日期參數(shù),設定一個時間區(qū)間,匹配此時間區(qū)間內(nèi)的請求。
4. Cookie:需要指定兩個參數(shù),分別為name和regexp(正則表達式),也可以理解Key和Value,匹配具有給定名稱且其值與正則表達式匹配的Cookie。
5. Header:需要兩個參數(shù)header和regexp(正則表達式),也可以理解為Key和Value,匹配請求攜帶信息。
6. Host:匹配當前請求是否來自于設置的主機。
7. Method:可以設置一個或多個參數(shù),匹配HTTP請求,比如GET、POST
8. Path:匹配指定路徑下的請求,可以是多個用逗號分隔
9. Query:需要指定一個或者多個參數(shù),一個必須參數(shù)和一個可選的正則表達式,匹配請求中是否包含第一個參數(shù),如果有兩個參數(shù),則匹配請求中第一個參數(shù)的值是否符合正則表達式。
10. RemoteAddr:匹配指定IP或IP段,符合條件轉(zhuǎn)發(fā)。
11. Weight:需要兩個參數(shù)group和weight(int),實現(xiàn)了路由權(quán)重功能,按照路由權(quán)重選擇同一個分組中的路由
spring cloud gateway Route Predicate
常用斷言演示
After
匹配在指定時間之后發(fā)生的請求,可以對應提前上線業(yè)務
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
- After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
獲取當前時間
import java.time.ZonedDateTime;
public class DateTimeTest {
public static void main(String[] args) {
ZonedDateTime zonedDateTime = ZonedDateTime.now();//默認時區(qū)
System.out.println(zonedDateTime);
}
}
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān),
After后時間為當前時間之前,請求OK
After后時間為當前時間之后,請求404
當這個After理解了以后,剩下的關(guān)于日期時間的設置Before、Between道理都是一樣的,只不過是限定不同的日期時間區(qū)間.
Cookie
需要指定兩個參數(shù),分別為name和regexp(正則表達式),也可以理解Key和Value,匹配具有給定名稱且其值與正則表達式匹配的Cookie。
簡單理解就是路由規(guī)則會通過獲取Cookie name值和正則表達式去匹配,如果匹配上就會執(zhí)行路由,如果匹配不上則不執(zhí)行。
我們可以分為兩種情況演示,Cookie匹配,Cookie不匹配
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
# - After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
- Cookie=username,[a-z]+ # 匹配Cookie的key和value(正則表達式)
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān),
通過postman來進行測試
http://localhost:9999/lwz/get
當Cookie匹配時:
?
當Cookie不匹配時:
?
Header
需要兩個參數(shù)header和regexp(正則表達式),也可以理解為Key和Value,匹配請求攜帶信息。
實際上就是請求頭攜帶的信息,官網(wǎng)給出的案例是X-Request-Id,那我們就用這個做實驗
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
# - After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
# - Cookie=username,[a-z]+ # 匹配Cookie的key和value(正則表達式)
- Header=X-Request-Id, \d+
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān),
通過postman來進行測試
匹配
不匹配
Host
匹配當前請求是否來自于設置的主機。
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
# - After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
# - Cookie=username,[a-z]+ # 匹配Cookie的key和value(正則表達式)
# - Header=X-Request-Id, \d+
- Host=**.lwz.cn #匹配當前的主機地址發(fā)出的請求
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān),
通過postman來進行測試
匹配
不匹配
Method
可以設置一個或多個參數(shù),匹配HTTP請求,比如GET、POST
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
# - After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
# - Cookie=username,[a-z]+ # 匹配Cookie的key和value(正則表達式)
# - Header=X-Request-Id, \d+
# - Host=**.lwz.cn #匹配當前的主機地址發(fā)出的請求
- Method=GET,POST # 匹配GET請求或者POST請求
Query
需要指定一個或者多個參數(shù),一個必須參數(shù)和一個可選的正則表達式,匹配請求中是否包含第一個參數(shù),如果有兩個參數(shù),則匹配請求中第一個參數(shù)的值是否符合正則表達式。
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
# - After=2023-06-17T23:43:56.904+08:00[Asia/Shanghai] # 在這個時間之后的請求都能通過
# - Cookie=username,[a-z]+ # 匹配Cookie的key和value(正則表達式)
# - Header=X-Request-Id, \d+
# - Host=**.lwz.cn #匹配當前的主機地址發(fā)出的請求
# - Method=GET,POST # 匹配GET請求或者POST請求
- Query=id,.+ # 匹配請求參數(shù),這里如果需要匹配多個參數(shù),可以寫多個Query
測試:
啟動Nacos、9003和9004和9999網(wǎng)關(guān),
通過postman來進行測試
Weight
需要兩個參數(shù)group和weight(int),實現(xiàn)了路由權(quán)重功能,按照路由權(quán)重選擇同一個分組中的路由
官網(wǎng)提供的演示yml
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
該路由會將約 80% 的流量轉(zhuǎn)發(fā)到[weighthigh.org](https://weighthigh.org/),將約 20% 的流量[轉(zhuǎn)發(fā)](https://weighlow.org/)到[weightlow.org](https://weighlow.org/)
Predicate就是為了實現(xiàn)一組匹配規(guī)則,讓請求過來找到對應的Route進行處理。
7、GateWay的Filter
路由過濾器允許以某種方式修改傳入的 HTTP 請求或傳出的 HTTP 響應。路由過濾器的范圍是特定的路由。Spring Cloud Gateway 包含許多內(nèi)置的 GatewayFilter 工廠。
內(nèi)置Filter
1. GateWay內(nèi)置的Filter生命周期為兩種:pre(業(yè)務邏輯之前)、post(業(yè)務邏輯之后)
2. GateWay本身自帶的Filter分為兩種: GateWayFilter(單一)、GlobalFilter(全局)
spring cloud gateway filters
StripPrefix
該StripPrefix有一個參數(shù),parts。該parts參數(shù)指示在將請求發(fā)送到下游之前要從請求中剝離的路徑中的部分數(shù)。
具體演示
9003微服務上加一個context-path配置
server:
port: 9003
servlet:
context-path: /nacos-provider
現(xiàn)在9003的訪問路徑變?yōu)閔ttp://localhost:9003/nacos-provider/lwz/get
目前的網(wǎng)關(guān)9999配置信息為
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: false #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
為了保證斷言能夠匹配,此時通過網(wǎng)關(guān)的訪問地址應該改為:http://localhost:9999/lwz/nacos-provider/lwz/get,但是出現(xiàn)了404因為多了一層路徑http://localhost:9003/lwz/nacos-provider/lwz/get
測試:
?
?
?
那么如果想要解決,我們應該在轉(zhuǎn)發(fā)的時候去地址中最前面的/lwz,所以我們就需要使用FIlter:StripPrefix
server:
port: 9999
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: false #開啟自動路由功能(此時可以關(guān)閉)
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務名
uri: lb://nacos-provider # 匹配提供服務的路由地址
predicates: # 斷言
- Path=/lwz/**
filters:
- StripPrefix=1 # 去掉地址中的第一部分
# http://localhost:9999/lwz/nacos-provider/lwz/get
# http://localhost:9999/nacos-provider/lwz/get
測試:
成功轉(zhuǎn)發(fā)
自定義Filter
要實現(xiàn)GateWay自定義過濾器,那么我們需要實現(xiàn)兩個接口GlobalFilter、Ordered
具體演示
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
@Component
@Slf4j
public class MyFilter implements Ordered, GlobalFilter {
/**
* @param exchange 可以拿到對應的request和response
* @param chain 過濾器鏈
* @return 是否放行
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String username = exchange.getRequest().getQueryParams().getFirst("username");
log.info("*************MyFilter:"+new Date());
if(username == null){
log.info("**********用戶名為null,非法用戶,請求被拒絕!");
//如果username為空,返回狀態(tài)碼為406,不可接受的請求
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 加載過濾器的順序
* @return 整數(shù)數(shù)字越小優(yōu)先級越高
*/
@Override
public int getOrder() {
return 0;
}
}
測試,此時我們的邏輯是在訪問同時要傳入username參數(shù)同時不能為空,否則不會放行本次請求。
傳入正確參數(shù):
?未傳入正確參數(shù):
2023-06-18 00:20:31.277 INFO 8096 --- [ctor-http-nio-2] com.lwz.springcloud9999.config.MyFilter : *************MyFilter:Sun Jun 18 00:20:31 CST 2023
2023-06-18 00:20:31.277 INFO 8096 --- [ctor-http-nio-2] com.lwz.springcloud9999.config.MyFilter : **********用戶名為null,非法用戶,請求被拒絕!
Spring Cloud Alibaba - Sentinel(一)
Spring Cloud Alibaba - Nacos文章來源:http://www.zghlxwxcb.cn/news/detail-499988.html
是日已過,命亦隨減;如少水魚,斯有何樂;當勤精進,如救頭燃;但念無常,慎勿放逸;文章來源地址http://www.zghlxwxcb.cn/news/detail-499988.html
到了這里,關(guān)于Spring Cloud Gateway的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!