Spring Cloud Gateway 網關的使用

在之前的學習中,所有的微服務接口都是對外開放的,這就意味著用戶可以直接訪問,為了保證對外服務的安全性,服務端實現的微服務接口都帶有一定的權限校驗機制,但是由于使用了微服務,就需要每一個服務都進行一個校驗,當校驗邏輯需要修改時,又得修改多個應用,增加了開發負擔,一個解決方式就是引入 API 網關,類似整個微服務架構的門面,所有的外部客戶端都需要經過它來進行調度和過濾,相當于前臺,需要辦理什么業務,經過前臺的確認之后會引導用戶去對應的服務臺

作為網關,具有以下的幾個核心功能:

  1. 權限控制:對用戶進行權限校驗,如果校驗失敗就進行攔截
  2. 動態路由:一切請求先經過網關,但網關不處理業務,而是根據某種規則,把請求發送到某個微服務
  3. 負載均衡:當路由的目標服務有多個時,進行負載均衡
  4. 限流:當請求流量過高時,按照網關中配置微服務能夠接受的流量進行放行,避免服務壓力過大

Gateway

1. Gateway 的使用

首先需要創建一個單獨的 Gateway 的服務,除了引入 gateway 的依賴之外,還需要引入 nacos 和 loadbalancer 的依賴

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><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-loadbalancer</artifactId></dependency>
</dependencies>

然后就需要對網關進行配置:

spring:application:name: gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes:  #網關路由配置- id: order-service #自定義路由規則iduri: lb://order-service/  #目標服務地址predicates:  #路由條件(滿足條件才會被通行)- Path=/order/**

來解釋一下上面的配置:

由于需要用到 Nacos 的服務發現功能,所以要把 Nacos 的配置也添加上,之后就是網關的路由配置,自定義一個路由規則 id 作為唯一標識符,方便后續對該規則進行管理和引用,然后就是目標服務地址, lb 表示使用負載均衡器將請求轉發到名為 order-service 的服務,并設置了路由條件,請求的路徑必須以 /order/ 開頭

配置好之后啟動服務,此時就可以通過網關服務來獲取資源了

關于多個服務和多個路由條件的配置:

routes:  #網關路由配置- id: order-service #自定義路由規則iduri: lb://order-service/  #目標服務地址predicates:  #路由條件(滿足條件才會被通行)- Path=/order/**,/feign/**- id: product-serviceuri: lb://product-servicepredicates:- Path=/product/**

2. Route Predicate Factories

在上面的配置中,使用 predicates 來配置路由條件,其中寫的規則只是字符串形式,這些字符串會被 Route Predicate Factory (路由斷言工廠,也稱為路由謂詞工廠)讀取并處理,轉變為路由判斷條件

https://docs.spring.io/spring-cloud-gateway/reference/spring-cloudgateway/request-predicates-factories.html

也就是這 12 種基本的實現:

來演示一下 After 的使用,如果不符合條件就會不能夠訪問

predicates:  #路由條件(滿足條件才會被通行)- Path=/order/**,/feign/**- After=2026-01-12T18:10:21.024727900+08:00[Asia/Shanghai]

3. Gateway Filter Factories

Predicate 是決定了請求由哪一個路由處理,Filter 過濾器是在請求處理前后做一些的邏輯的處理

Filter 又分為 Pre 和 Post 兩種類型:

Pre 類型過濾器:路由處理之前執行,也就是請求轉發給后端服務之前,例如對請求進行限流,添加額外的請求頭信息等

Post 類型過濾器:請求執行完成后,將結果返回給客戶端之前執行,例如修改響應體的主體內容,對響應路徑進行重寫等

Spring Cloud Gateway 中內置了很多的過濾器,用于攔截和處理 web 請求,根據作用范圍可以分為 GatewayFilter (作用到單個路由或者一個分組的路由上),GlobalFilter(作用到所有的路由上)

來演示一下 AddRequestParameter 用法:

接下來再訪問接口,即使 id 不傳值也通過過濾器處理之后就被賦值了

除了 AddRequestParameter,觀望中還提供了很多其它的過濾器

AddRequestHeader GatewayFilter Factory :: Spring Cloud Gateway

RequestRateLimiter 可以對通過網關的請求進行限流操作,采用的是令牌桶的算法

關于限流的算法有以下幾種:

  1. 固定窗口:將時間劃分為固定大小的窗口,每個窗口有一個計數器,用于記錄在該窗口內允許通過的請求數量,每通過一個請求計數器就加一,當計數器達到設定的閾值就不允許請求通過,缺點也是非常明顯,比如設定 10 分鐘可以通過 10000 個請求,前 9 分鐘都沒有請求,最后 1 分鐘處理 10000 個請求也符合要求,顯然是不合理的
  2. 滑動窗口:同樣將時間劃分為多個小的時間窗口,但不是按固定的大窗口重置計數器,而是將窗口滑動,這也就解決了固定窗口出現的問題,不過需要記錄多個小窗口的信息,性能開銷比較大
  3. 漏桶算法:就像一個漏斗型的水桶,當請求到達時,會先進入漏桶,如果漏桶未滿,則允許請求通過;如果漏桶已滿,則拒絕請求,桶以恒定的速率出水,代表處理請求的速率,無論流入的速率如何,流出的速率始終保持一致,這也就導致了不能夠處理突發的大流量
  4. 令牌桶算法:在漏桶的基礎上,令牌桶中會以一定的速率生成令牌,當流量小的時候,桶中就會不斷積累令牌,當遇到突發的大流量,就可以直接拿著這些令牌通過,剩余的就排隊等待令牌的生成,排隊等待這種處理方式,還可以結合其他策略,比如當排隊隊列過長時,為了避免資源過度占用,可能會對部分請求進行拒絕;或者根據業務的優先級,優先處理高優先級請求等。

再來看下一個過濾器:

Retry 就是根據當前返回的狀態碼來進行重試,可以設置狀態碼和重試次數

在上面的配置中都是使用 filter 進行配置的,如果使用 Default Filters 配置的話就是對全部路由生效

來使用 default-filters 配置一下 retry,然后把狀態碼設置為 502

之后就重新請求了 3 次

GlobalFilter 是全局過濾器,會應用到所有的路由請求上,全局過濾器通常用于實現安全性,性能監控和日志記錄等相關的全局功能

關于負載均衡,在之前的使用中就已經用到了,也就是 GlobalFilter

下面看一下 Metrics 怎么使用,首先需要引入下面的依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

然后再開啟 metrics 的配置

然后再添加一下配置,用來監控詳細的信息,在 /actuator 下可以查到所有監控的鏈接和信息

過濾器的執行順序:

當一個項目中,既有 GatewayFilter 又有 GlobalFilter 時,請求路由后,網關會把當前項目中的 GatewayFilter 和 GlobalFilter 合并到一個 過濾器鏈中,并進行排序,依次執行過濾器

每一個過濾器都必須指定一個 int 類型的 order 值,默認值為 0 ,來表示過濾器的優先級,order 值越小,優先級越高,執行順序越靠前

Filter 通過實現 Order 接口或者添加@Order注解來指定 order 值,Spring Cloud Gateway 提供的 Filter 由 Spring 指定,用戶也可以自定義 Filter,如果過濾器的 order 值一樣,會按照 defaultFilter > GatewayFilter > GlobalFilter 的順序執行

4. 自定義過濾器

4.1. 自定義 GlobalFilter

全局過濾器需要實現 GlobalFilter,Ordered 接口,然后重寫 filter 和 getOrder 方法

@Slf4j
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//Pre執行邏輯log.info("Pre Global Filter...");return chain.filter(exchange).then(Mono.fromRunnable(()->{//Post執行邏輯log.info("Post Global Filter...");}));}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE; //設置優先級}
}

關于 Mono 方法參數的說明:

之后再去發起請求,自定義的全局過濾器已經生效了

4.2. 自定義 GatewayFilter

如果需要自定義可配置的 GatewayFilter,就需要創建一個過濾器工廠,根據讀取到的配置來構造對象

定義一個類用來存儲從配置文件中讀取到的配置信息

@Data
public class CustomConfig {private String name;
}

創建一個過濾器工廠 CustomGatewayFilterFactory 繼承 AbstractGatewayFilterFactory 類,然后再實現 Ordered 接口,并添加過濾器的邏輯

@Slf4j
@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {public CustomGatewayFilterFactory() {super(CustomConfig.class);}@Overridepublic GatewayFilter apply(CustomConfig config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//Pre類型log.info("Pre Filter,config{}",config);return chain.filter(exchange).then(Mono.fromRunnable(()->{log.info("Post Filter,config{}",config);}));}};}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE;}
}

配置文件中把自定義的過濾器名稱添加上,然后還需要添加傳入的參數,這里過濾器的名稱取的是 CustomGatewayFilterFactory 除去 GatewayFilterFactory,按照規范自定義過濾器工廠需要以 GatewayFilterFactory 為后綴

之后再啟動服務,自定義的 GatewayFilter 也生效了,并且在指定優先級相同的條件下,先執行 GatewayFilter 再執行 GlobalFilter

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72406.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72406.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72406.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

webstorm的Live Edit插件配合chrome擴展程序JetBrains IDE Support實現實時預覽html效果

前言 我們平時在前端網頁修改好代碼要點擊刷新再去看修改的效果&#xff0c;這樣比較麻煩&#xff0c;那么很多軟件都提供了實時預覽的功能&#xff0c;我們一邊編輯代碼一邊可以看到效果。下面說的是webstorm。 1 Live Edit 首先我們需要在webstorm的settings里安裝插件Live …

map的operator[]的實現

map的operator[]的實現 operator[]里包含插入操作&#xff0c;所以我們先看一下首先看一下map的insert函數 返回值是一個pair類型。正常的常見的insert&#xff0c;插入成功返回true&#xff0c;失敗返回false 這里設計的insert不單單返回布爾值&#xff0c;而是返回一個pair…

定時器的編碼器接口模式

選擇編碼器接口模式的方法是&#xff1a;如果計數器只在TI2的邊沿計數&#xff0c;則置TIMx_SMCR寄存器中的SMS001&#xff0c;如果只在TI1邊沿計數&#xff0c;則置SMS010&#xff0c;如果計數器同時在TI1和TI2邊沿計數&#xff0c;則置SMS 011 明確一點&#xff0c;計數器…

Openshift配置默認調度

配置默認調度選擇角色為worker的機器運行pod。 編輯scheduler oc edit schedulers.config.openshift.iospec:defaultNodeSelector: node-role.kubernetes.io/worker ## 添加這一段如果pod需要運行在非worker主機&#xff0c;需要配置pod所在的項目添加注解 openshift.io/node…

突破光學成像局限:全視野光學血管造影技術新進展

全視野光學血管造影&#xff08;FFOA&#xff09;作為一種實時、無創的成像技術&#xff0c;能夠提取生物血液微循環信息&#xff0c;為深入探究生物組織的功能和病理變化提供關鍵數據。然而&#xff0c;傳統FFOA成像方法受到光學鏡頭景深&#xff08;DOF&#xff09;的限制&am…

OpenHarmony 進階——HDF 驅動框架的原理小結

文章大綱 引言一、HDF的驅動加載&#xff08;驅動安裝&#xff09;方式1、動態加載&#xff08;主要是uhdf&#xff09;2、靜態加載(主要是khdf)2.1、驅動入口實現2.1.1、Bind接口2.1.2、Init接口2.1.3、Release接口 2.2、HDF_INIT 驅動入口符號2.3、獲取驅動列表2.4、獲取設備…

大模型應用:多輪對話(prompt工程)

概述 在與大型語言模型&#xff08;如ChatGPT&#xff09;交互的過程中&#xff0c;我們常常體驗到與智能助手進行連貫多輪對話的便利性。那么&#xff0c;當我們開啟一個新的聊天時&#xff0c;系統是如何管理聊天上下文的呢&#xff1f; 一、初始上下文的建立 1. 創建新會…

如何為JAR設置定時重啟?

AI越來越火了&#xff0c;我們想要不被淘汰就得主動擁抱。推薦一個人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;最重要的屌圖甚多&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 前面我們說過了如何將jar交由Systemctl管理&#xff0c;下面我們…

神碼AC-AP無線部署

神碼AC-AP無線部署: 1.設置基礎網絡 交換機設置 service dhcp ! ip dhcp pool ap (AP用地址) network-address 10.1.1.0 255.255.255.0 default-router 10.1.1.254 option 43 hex 010401010101 &#xff08;AC IP地址16進制&#…

【Redis】常用命令匯總

Redis 作為高性能的鍵值存儲數據庫&#xff0c;提供了豐富的命令集&#xff0c;主要涵蓋 字符串 (String)、哈希 (Hash)、列表 (List)、集合 (Set)、有序集合 (ZSet)、鍵 (Keys)、Geo&#xff08;地理位置&#xff09;、HyperLogLog&#xff08;基數統計&#xff09;、Bitmap&a…

Redis - 高可用實現方案解析:主從復制與哨兵監控

文章目錄 Pre概述Redis 高可用實現方案一、主從復制機制1.1 全量同步流程1.2 增量同步&#xff08;PSYNC&#xff09;流程 二、哨兵監控機制2.1 故障轉移時序流程 三、方案對比與選型建議四、生產環境實踐建議 Pre Redis-入門到精通 Redis進階系列 Redis進階 - Redis主從工作…

2025年滲透測試面試題總結-02(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 阿里云安全實習 一、代碼審計經驗與思路 二、越權漏洞原理與審計要點 三、SSRF漏洞解析與防御 四、教…

水滴tabbar canvas實現思路

廢話不多說之間看效果圖,只要解決了這個效果水滴tabbar就能做出來了 源碼地址 一、核心實現步驟分解 布局結構搭建 使用 作為繪制容器 設置 width=600, height=200 基礎尺寸 通過 JS 動態計算實際尺寸(適配高清屏) function initCanvas() {// 獲取設備像素比(解決 Re…

解決各大瀏覽器中http地址無權限調用麥克風攝像頭問題(包括谷歌,Edge,360,火狐)后續會陸續補充

項目場景&#xff1a; 在各大瀏覽器中http地址調用電腦麥克風攝像頭會沒有權限&#xff0c;http協議無法使用多媒體設備 原因分析&#xff1a; 為了用戶的隱私安全&#xff0c;http協議無法使用多媒體設備。因為像攝像頭和麥克風屬于可能涉及重大隱私問題的API&#xff0c;ge…

網絡安全蜜罐產品研究現狀

&#x1f345; 點擊文末小卡片 &#xff0c;免費獲取網絡安全全套資料&#xff0c;資料在手&#xff0c;漲薪更快 一、知識點總結 1、蜜罐&#xff08;Honeypot&#xff09;&#xff1a;誘捕攻擊者的一個陷阱。 2、蜜網&#xff08;Honeynet&#xff09;&#xff1a;采用了技術…

el-card 結合 el-descriptions 作為信息展示

記錄下el-card 組合 el-descriptions 實現動態展示信息 文章結構 實現效果1. el-descriptions 組件使用1.1 結合v-for實現列表渲染1.2 解析 2. 自定義 el-descriptions 樣式2.1 修改背景色、字體顏色2.2 調整字體大小2.3 解析 3. el-card 結合 el-descriptions 作為信息展示3.…

【Java---數據結構】鏈表 LinkedList

1. 鏈表的概念 鏈表用于存儲一系列元素&#xff0c;由一系列節點組成&#xff0c;每個節點包含兩部分&#xff1a;數據域和指針域。 數據域&#xff1a;用于存儲數據元素 指針域&#xff1a;用于指向下一個節點的地址&#xff0c;通過指針將各個節點連接在一起&#xff0c;形…

python-leetcode-不同的二叉搜索樹 II

95. 不同的二叉搜索樹 II - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class S…

動態規劃/貪心算法

一、動態規劃 動態規劃 是一種用于解決優化問題的算法設計技術&#xff0c;尤其適用于具有重疊子問題和最優子結構性質的問題。它通過將復雜問題分解為更簡單的子問題&#xff0c;并保存這些子問題的解以避免重復計算&#xff0c;從而提高效率。 動態規劃的核心思想 最優子結…

2月28日,三極管測量,水利-51單片機

眾所周知&#xff0c;三極管&#xff08;BJT&#xff09;有三個管腳&#xff0c;基極&#xff08;B&#xff09;、集電極&#xff08;C&#xff09;、發射極&#xff08;E&#xff09;&#xff0c;在實際應用中&#xff0c;不可避免地會遇到引腳辨別的問題。接下來就講下三極管…