新聞中心
在微服務(wù)架構(gòu)中,通常一個系統(tǒng)會被拆分為多個微服務(wù),面對這么多微服務(wù)客戶端應(yīng)該如何去調(diào)用呢?如果沒有其他更優(yōu)方法,我們只能記錄每個微服務(wù)對應(yīng)的地址,分別去調(diào)用,但是這樣會有很多的問題和潛在因素。

創(chuàng)新互聯(lián)建站長期為成百上千客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為融安企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、做網(wǎng)站,融安網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
- 客戶端多次請求不同的微服務(wù),會增加客戶端代碼和配置的復(fù)雜性,維護成本比價高。
- 認證復(fù)雜,每個微服務(wù)可能存在不同的認證方式,客戶端去調(diào)用,要去適配不同的認證。
- 存在跨域的請求,調(diào)用鏈有一定的相對復(fù)雜性(防火墻 / 瀏覽器不友好的協(xié)議)。
- 難以重構(gòu),隨著項目的迭代,可能需要重新劃分微服務(wù)。
為了解決上面的問題,微服務(wù)引入了 網(wǎng)關(guān) 的概念,網(wǎng)關(guān)為微服務(wù)架構(gòu)的系統(tǒng)提供簡單、有效且統(tǒng)一的API路由管理,作為系統(tǒng)的統(tǒng)一入口,提供內(nèi)部服務(wù)的路由中轉(zhuǎn),給客戶端提供統(tǒng)一的服務(wù),可以實現(xiàn)一些和業(yè)務(wù)沒有耦合的公用邏輯,主要功能包含認證、鑒權(quán)、路由轉(zhuǎn)發(fā)、安全策略、防刷、流量控制、監(jiān)控日志等。
網(wǎng)關(guān)在微服務(wù)中的位置:
自己手繪的
官網(wǎng)上的
網(wǎng)關(guān)對比
- Zuul 1.0: Netflix開源的網(wǎng)關(guān),使用Java開發(fā),基于Servlet架構(gòu)構(gòu)建,便于二次開發(fā)。因為基于Servlet內(nèi)部延遲嚴重,并發(fā)場景不友好,一個線程只能處理一次連接請求。
- Zuul 2.0: 采用Netty實現(xiàn)異步非阻塞編程模型,一個CPU一個線程,能夠處理所有的請求和響應(yīng),請求響應(yīng)的生命周期通過事件和回調(diào)進行處理,減少線程數(shù)量,開銷較小。
- GateWay: 是Spring Cloud的一個全新的API網(wǎng)關(guān)項目,替換Zuul開發(fā)的網(wǎng)關(guān)服務(wù),基于Spring5.0 + SpringBoot2.0 + WebFlux(基于?性能的Reactor模式響應(yīng)式通信框架Netty,異步?阻塞模型)等技術(shù)開發(fā),性能高于Zuul。
- Nginx+lua: 性能要比上面的強很多,使用Nginx的反向代碼和負載均衡實現(xiàn)對API服務(wù)器的負載均衡以及高可用,lua作為一款腳本語言,可以編寫一些簡單的邏輯,但是無法嵌入到微服務(wù)架構(gòu)中。
- Kong: 基于OpenResty(Nginx + Lua模塊)編寫的高可用、易擴展的,性能高效且穩(wěn)定,支持多個可用插件(限流、鑒權(quán))等,開箱即可用,只支持HTTP協(xié)議,且二次開發(fā)擴展難,缺乏更易用的管理和配置方式。
GateWay
官方文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter。
Spring Cloud Gateway 是Spring Cloud的一個全新的API網(wǎng)關(guān)項目,目的是為了替換掉Zuul1,它基于Spring5.0 + SpringBoot2.0 + WebFlux(基于?性能的Reactor模式響應(yīng)式通信框架Netty,異步?阻塞模型)等技術(shù)開發(fā),性能?于Zuul,官?測試,Spring Cloud GateWay是Zuul的1.6倍 ,旨在為微服務(wù)架構(gòu)提供?種簡單有效的統(tǒng)?的API路由管理?式。
- 可以與Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等組件配合使用,實現(xiàn)路由轉(zhuǎn)發(fā)、負載均衡、熔斷、鑒權(quán)、路徑重寫、?志監(jiān)控等。
- Gateway還內(nèi)置了限流過濾器,實現(xiàn)了限流的功能。
- 設(shè)計優(yōu)雅,容易拓展。
基本概念
路由(Route)是GateWay中最基本的組件之一,表示一個具體的路由信息載體,主要由下面幾個部分組成:
- id:路由唯一標識,區(qū)別于其他的route。
- url:路由指向的目的地URL,客戶端請求最終被轉(zhuǎn)發(fā)到的微服務(wù)。
- order:用于多個Route之間的排序,數(shù)值越小越靠前,匹配優(yōu)先級越高。
- predicate:斷言的作用是進行條件判斷,只有斷言為true,才執(zhí)行路由。
- filter: 過濾器用于修改請求和響應(yīng)信息。
核心流程
核心概念:
- Gateway Client? 向Spring Cloud Gateway 發(fā)送請求
- 請求首先會被HttpWebHandlerAdapter 進行提取組裝成網(wǎng)關(guān)上下文
- 然后網(wǎng)關(guān)的上下文會傳遞到DispatcherHandler? ,它負責(zé)將請求分發(fā)給RoutePredicateHandlerMapping
- RoutePredicateHandlerMapping 負責(zé)路由查找,并根據(jù)路由斷言判斷路由是否可用
- 如果過斷言成功,由 FilteringWebHandler 創(chuàng)建過濾器鏈并調(diào)用
- 通過特定于請求的Fliter? 鏈運行請求,F(xiàn)ilter 被虛線分隔的原因是Filter可以在發(fā)送代理請求之前(pre)和之后(post)運行邏輯
- 執(zhí)行所有pre過濾器邏輯。然后進行代理請求。發(fā)出代理請求后,將運行“post”過濾器邏輯。
- 處理完畢之后將Response? 返回到Gateway 客戶端
Filter過濾器:
- Filter在pre類型的過濾器可以做參數(shù)效驗、權(quán)限效驗、流量監(jiān)控、日志輸出、協(xié)議轉(zhuǎn)換等。
- Filter在post類型的過濾器可以做響應(yīng)內(nèi)容、響應(yīng)頭的修改、日志輸出、流量監(jiān)控等
核心思想
當用戶發(fā)出請求達到 GateWay 之后,會通過一些匹配條件,定位到真正的服務(wù)節(jié)點,并且在這個轉(zhuǎn)發(fā)過程前后,進行一些細粒度的控制,其中 Predicate(斷言) 是我們的匹配條件,F(xiàn)ilter 是一個攔截器,有了這兩點,再加上URL,就可以實現(xiàn)一個具體的路由,核心思想:路由轉(zhuǎn)發(fā)+執(zhí)行過濾器鏈。
這個過程就好比考試,我們考試首先要找到對應(yīng)的考場,我們需要知道考場的地址和名稱(id和url),然后我們進入考場之前會有考官查看我們的準考證是否匹配(斷言),如果匹配才會進入考場,我們進入考場之后,(路由之前)會進行身份的登記和考試的科目,填寫考試信息,當我們考試完成之后(路由之后)會進行簽字交卷,走出考場,這個就類似我們的過濾器。
Route(路由) :構(gòu)建網(wǎng)關(guān)的基礎(chǔ)模塊,由ID、目標URL、過濾器等組成。
Predicate(斷言) :開發(fā)人員可以匹配HTTP請求中的內(nèi)容(請求頭和請求參數(shù)),如果請求斷言匹配則進行路由。
Filter(過濾) :GateWayFilter的實例,使用過濾器,可以在請求被路由之前或者之后對請求進行修改。
框架搭建
通過上述講解已經(jīng)了解了基礎(chǔ)概念,我們來動手搭建一個GateWay項目,來看看它到底是如何運行的 新建項目:cloud-alibaba-gateway-9006。
版本對應(yīng):
GateWay屬于SprinigCloud且有web依賴,在我們導(dǎo)入對應(yīng)依賴時,要注意版本關(guān)系,我們這里使用的版本是 2.2.x的版本,所以配合使用的Hoxton.SR5版本。
在這里我們要注意的是引入GateWay一定要刪除spring-boot-starter-web依賴,否則會有沖突無法啟動。
父類pom引用:
Hoxton.SR5
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud-gateway-varsion}
pom
import
子類POM引用:
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-gateway
2.2.5.RELEASE
org.projectlombok
lombok
yml配置:
server:
port: 9006
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: false #開啟注冊中心路由功能
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務(wù)名
uri: http://localhost:9001/nacos-provider # 匹配提供服務(wù)的路由地址 lb://表示開啟負載均衡
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
我們在之前的cloud-alibaba-nacos-9001項目中添加下面測試代碼:
@RestController
@RequestMapping("/mxn")
public class DemoController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/hello")
public String hello(){
return "hello world ,my port is :"+serverPort;
}
}
啟動Nacos、cloud-alibaba-nacos-9001、cloud-alibaba-gateway-9006通過gateway網(wǎng)關(guān)去訪問9001的mxn/order看看。
首先我們在Nacos中看到我們服務(wù)是注冊到Nacos中了。
然后我們訪問http://localhost:9001/mxn/hello?,確保是成功的,再通過http://localhost:9006/mxn/hello去訪問,也是OK,說明我們GateWay搭建成功,我們進入下一步。
在上述方法中我們是通過YML去完成的配置,GateWay還提供了另外一種配置方式,就是通過代碼的方式進行配置,@Bean 注入一個 RouteLocator。
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 {
/*
配置了一個id為path_mxn的路由規(guī)則
當訪問地址http://localhost:9999/mxn/**
就會轉(zhuǎn)發(fā)到http://localhost:9001/nacos-provider/mxn/任何地址
*/
@Bean
public RouteLocator gateWayConfigInfo(RouteLocatorBuilder routeLocatorBuilder){
// 構(gòu)建多個路由routes
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
// 具體路由地址
routes.route("path_mxn",r -> r.path("/mxn/**").uri("http://localhost:9001/nacos-provider")).build();
// 返回所有路由規(guī)則
return routes.build();
}
}
我們可以將路由注釋掉之后看一下,重啟9006服務(wù),訪問地址http://localhost:9006/mxn/hello 就可以轉(zhuǎn)發(fā)到9001中具體的接口中。
這里并不推薦,使用代碼的方式來進行配置gateWay,大家有個了解就可以,因為代碼的配置維護的成本比較高,而且對于一些需要修改的項,需要改代碼才可以完成,這樣不利于維護和拓展,所以還是推薦大家使用yml進行配置。
GateWay負載均衡
在上述的講解中,我們已經(jīng)掌握了 GateWay 的一些基本配置和兩種使用方式,下面我們就來講解一下 GateWay 如何實現(xiàn)負載均衡
我們只需要在9006中添加lb://nacos-provider就可以顯示負載均衡。
當我們?nèi)ピL問http://localhost:9006/mxn/hello的時候,就可以看到9001和9002不停的切換。
Predicate 斷言
在這一篇中我們來研究一下 斷言 ,我們可以理解為:當滿足條件后才會進行轉(zhuǎn)發(fā)路由,如果是多個,那么多個條件需要同時滿足。
在官方提供的斷言種類有11種(最新的有12種類型):
具體地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories。
- After:匹配在指定日期時間之后發(fā)生的請求。
- Before:匹配在指定日期之前發(fā)生的請求。
- Between:需要指定兩個日期參數(shù),設(shè)定一個時間區(qū)間,匹配此時間區(qū)間內(nèi)的請求。
- Cookie:需要指定兩個參數(shù),分別為name和regexp(正則表達式),也可以理解Key和Value,匹配具有給定名稱且其值與正則表達式匹配的Cookie。
- Header:需要兩個參數(shù)header和regexp(正則表達式),也可以理解為Key和Value,匹配請求攜帶信息。
- Host:匹配當前請求是否來自于設(shè)置的主機。
- Method:可以設(shè)置一個或多個參數(shù),匹配HTTP請求,比如GET、POST。
- Path:匹配指定路徑下的請求,可以是多個用逗號分隔。
- Query:需要指定一個或者多個參數(shù),一個必須參數(shù)和一個可選的正則表達式,匹配請求中是否包含第一個參數(shù),如果有兩個參數(shù),則匹配請求中第一個參數(shù)的值是否符合正則表達式。
- RemoteAddr:匹配指定IP或IP段,符合條件轉(zhuǎn)發(fā)。
- Weight:需要兩個參數(shù)group和weight(int),實現(xiàn)了路由權(quán)重功能,按照路由權(quán)重選擇同一個分組中的路由。
After :表示配置時間之后才進行轉(zhuǎn)發(fā)。
時間戳獲取代碼,用于時間代碼的獲取:
public static void main(String[] args) {
ZonedDateTime zbj = ZonedDateTime.now();//默認時區(qū)
System.out.println(zbj);
}
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #開啟注冊中心路由功能
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務(wù)名
uri: lb://nacos-provider # 匹配提供服務(wù)的路由地址 lb://表示開啟負載均衡
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
- After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
如果在時間段之前訪問則404。
Before
匹配ZonedDateTime類型的時間,表示匹配在指定日期時間之前的請求,之后的請求則拒絕404錯誤。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
- Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
Between
Between 可以匹配ZonedDateTime類型的時間,由兩個ZonedDateTime參數(shù)組成,第一個參數(shù)為開始時間,第二參數(shù)為結(jié)束時間,逗號進行分隔,匹配在指定的開始時間與結(jié)束時間之內(nèi)的請求,配置如下:
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
- Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
Cookie
由兩個參數(shù)組成,分別為name(Key)和regexp(正則表達式)(Value),匹配具有給定名稱且其值與正則表達式匹配的Cookie。
路由規(guī)則會通過獲取Cookie name值和正則表達式去匹配,如果匹配上就會執(zhí)行路由,如果匹配不上則不執(zhí)行。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
- Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
小寫字母匹配成功:
數(shù)字匹配不成功:
Header
由兩個參數(shù)組成,第一個參數(shù)為Header名稱?,第二參數(shù)為Header的Value值,指定名稱的其值和正則表達式相匹配的Header的請求。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
# - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
- Header=headerName, \d+ # \d表示數(shù)字
請求頭攜帶數(shù)字斷言請求成功。
斷言字母匹配失?。?/p>
Host
匹配當前請求是否來自于設(shè)置的主機。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
# - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
# - Header=headerName, \d+ # \d表示數(shù)字
- Host=**.muxiaonong.com #匹配當前的主機地址發(fā)出的請求
滿足Host斷言,請求成功。
不滿足Host斷言失敗
Method
可以設(shè)置一個或多個參數(shù),匹配HTTP請求,比如POST,PUT,GET,DELETE。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
# - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
# - Header=headerName, \d+ # \d表示數(shù)字
# - Host=**.muxiaonong.com #匹配當前的主機地址發(fā)出的請求
- Method=POST,GET
GET斷言成功:
PUT斷言請求失?。?/p>
Query
由兩個參數(shù)組成,第一個為參數(shù)名稱(必須),第二個為參數(shù)值(可選-正則表達式),匹配請求中是否包含第一個參數(shù),如果有兩個參數(shù),則匹配請求中第一個參數(shù)的值是否符合第二個正則表達式。
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
# - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
# - Header=headerName, \d+ # \d表示數(shù)字
# - Host=**.muxiaonong.com #匹配當前的主機地址發(fā)出的請求
# - Method=POST,GET
- Query=id,.+ # 匹配任意請求參數(shù),這里如果需要匹配多個參數(shù),可以寫多個- Query=
斷言匹配 請求成功。
RemoteAddr
參數(shù)由CIDR 表示法(IPv4 或 IPv6)字符串組成,也就是匹配的ID地址,配置如下:
predicates: # 斷言
- Path=/mxn/** # 斷言,路徑相匹配進行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在這個時間之后的請求夠可以進行通過,之前的則不能進行訪問
# - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
# - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
# - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正則表達式)表示任意字母
# - Header=headerName, \d+ # \d表示數(shù)字
# - Host=**.muxiaonong.com #匹配當前的主機地址發(fā)出的請求
# - Method=POST,GET
# - Query=id,.+ # 匹配任意請求參數(shù),這里如果需要匹配多個參數(shù),可以寫多個Query
- RemoteAddr=192.168.1.1/24
RemoteAddr
需要兩個參數(shù)group和weight(int)權(quán)重數(shù)值,實現(xiàn)了路由權(quán)重功能,表示將相同的請求根據(jù)權(quán)重跳轉(zhuǎn)到不同的uri地址,要求group的名稱必須一致。
routes: # 路由
- id: weight_high #路由ID,沒有固定要求,但是要保證唯一,建議配合服務(wù)名
uri: https://blog.csdn.net/qq_14996421
predicates: # 斷言
- Weight=groupName,8
- id: weight_low #路由ID,沒有固定要求,但是要保證唯一,建議配合服務(wù)名
uri: https://juejin.cn/user/2700056290405815
predicates: # 斷言
- Weight=groupName,2
直接訪問http://localhost:9006/可以看到我們請求的地址成8/2比例交替顯示, 80% 的流量轉(zhuǎn)發(fā)到https://blog.csdn.net/qq_14996421,將約 20% 的流量轉(zhuǎn)發(fā)到https://juejin.cn/user/2700056290405815。
Predicate就是為了實現(xiàn)一組匹配規(guī)則,讓請求過來找到對應(yīng)的Route進行處理。如果有多個斷言則全部命中后進行處理。
GateWay Filter
路由過濾器允許修改傳入的HTTP請求或者返回的HTTP響應(yīng),路由過濾器的范圍是特定的路由。
Spring Cloud GateWay 內(nèi)置的Filter生命周期有兩種:pre(業(yè)務(wù)邏輯之前)、post(業(yè)務(wù)邏輯之后)。
GateWay本身自帶的Filter分為兩種:GateWayFilter(單一)、GlobalFilter(全局)。
GateWay Filter提供了豐富的過濾器的使用,單一的有32種,全局的有9種,有興趣的小伙伴可以了解一下。
官方參考網(wǎng)址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters。
StripPrefix
StripPrefix 在我們當前請求中,通過規(guī)則值去掉某一部分地址,比如我們有一臺服務(wù)中加入了一個前端nacos-provider想要通過這個去訪問,我們在項目cloud-alibaba-nacos-9001中加入 context-path。
server:
port: 9001
servlet:
context-path: /nacos-provider
現(xiàn)在9001的訪問路徑變?yōu)閔ttp://localhost:9001/nacos-provider/mxn/hello,但是如果我們通過網(wǎng)關(guān)去訪問路徑就會變成http://localhost:9006/mxn/nacos-provider/mxn/hello 這個時候我們通過這個路徑去訪問是訪問不成功的,想要解決這個方法,這個就用到了我們FIlter 中的 StripPrefix。
routes: # 路由
- id: nacos-provider #路由ID,沒有固定要求,但是要保證唯一,建議配合服務(wù)名
uri: lb://nacos-provider
predicates: # 斷言
- Path=/mxn/** # 匹配對應(yīng)地址
filters:
- StripPrefix=1 # 去掉地址中的第一部分
我們重新啟動9006項目,再去訪問。
自定義Filter
雖然Gateway給我們提供了豐富的內(nèi)置Filter,但是實際項目中,自定義Filter的場景非常常見,因此單獨介紹下自定義FIlter的使用。
想要實現(xiàn)GateWay自定義過濾器,那么我們需要實現(xiàn)GatewayFilter接口和Ordered接口。
@Slf4j
@Component
public class MyFilter implements Ordered, GlobalFilter {
/**
* @param exchange 可以拿到對應(yīng)的request和response
* @param chain 過濾器鏈
* @return 是否放行
*/
@Override
public Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {
//獲取第一個參數(shù)
String id = exchange.getRequest().getQueryParams().getFirst("id");
//打印當前時間
log.info("MyFilter 當前請求時間為:"+new Date());
//判斷用戶是否存在
if(StringUtils.isEmpty(id)){
log.info("用戶名不存在,非法請求!");
//如果username為空,返回狀態(tài)碼為407,需要代理身份驗證
exchange.getResponse().setStatusCode(HttpStatus.PROXY_AUTHENTICATION_REQUIRED);
// 后置過濾器
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 設(shè)定過濾器的優(yōu)先級,值越小則優(yōu)先級越高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
當我們訪問http://localhost:9006/mxn/nacos-provider/mxn/hello請求,沒有攜帶ID參數(shù),請求失敗。
當我們訪問http://localhost:9006/mxn/nacos-provider/mxn/hello?id=1請求,請求成功。
總結(jié)
到這里我們的GateWay就講解完了,對于GateWay的核心點主要有三個Route\Predicate\Filter,我們搞懂了這三點,基本上對于GateWay的知識就掌握的差不多了,GateWay核心的流程就是:路由轉(zhuǎn)發(fā)+執(zhí)行過濾器鏈。
網(wǎng)站標題:這篇SpringCloudGateWay詳解,你用的到
分享地址:http://m.fisionsoft.com.cn/article/cdggdgp.html


咨詢
建站咨詢
