--- 統一請求入口 Gateway ---

spring cloud gateway 官方文檔?Spring Cloud Gateway 中文文檔

什么是api網關

對于微服務的每個接口,我們都需要校驗請求的權限是否足夠,而微服務把項目細化除了許多個接口,若這些接口都要對服務進行權限校驗的話,那么無疑加重的代碼負擔和運行熟讀,而如果我使用一個統一的服務來對所有的請求進行權限校驗并將請求轉發到對應的服務,而服務的接口不對外暴露,那么就可以確保服務收到的請求是服務之間調用的,而不是用戶發起的請求調用的,而這個服務就是我們的網關,他是服務的守門神

api網關的結構如圖

他通常是后端服務的唯一入口,類似于門面模式,所有的請求都經過他手并受他掉調度,協調,過濾,如果有有多個相同的服務啟動了還可以使用負載均衡來平衡壓力

常見的開源的api網關的實現有zuul,gateway,nginx,kong

部署Gateway服務

引入依賴

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

gateway服務也需要注冊再注冊中心nacos中,這個spring-cloud-xxx(loadbalancer)和spring-cloud-starter-xxx(loadbalancer)依賴的區別是前者提供了負載均衡的核心api,但是沒有負載均衡的依賴的依賴,如果需要使用某些功能需要自己導入對應的依賴,而后者stater他提供開箱即用的體驗,他是一個空的jar包,但是會有一些元數據來告訴他需要導入哪些依賴來確保依賴運行

對項目寫一

個啟動類之后就可以路由配置了

gateway路由規則

可以寫在代碼中 不過很麻煩

寫在配置文件中要簡便許多?

uri也可以使用ws://或wss://來進行websocket請求的轉發可以直接轉發到固定的url或者通過服務發現,ws和wss的區別是前者是未加密的websocket連接后者是加密的websocket連接

http://和https:// 轉發到固定的http和https地址

Route Predicate Factories 路由斷言工廠

gateway提供了多種路由適配規則來適配多種情況

After需要指定一個ZonedDateTime類型的時間,他會匹配這個時間之后的請求,判斷依據是當前收到請求的時間
predicates: # 路由條件- After=2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Before在這個時間之前的請求
predicates: # 路由條件- Before=2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Between匹配倆個時間之間的請求
predicates: # 路由條件- Between=2025-09-02T13:45:35.359524+08:00[Asia/Shanghai], 2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Cookie包含指定的cookie,這個cookie的key是cool v是 這個hh可以是正則表達式
predicates:- Cookie=cool, hh
Header

該請求包含指定的Header字段

且key為haha v滿足\d+的正則表達式

predicates:- Header=haha, \d+
Host對請求頭中的Host進行匹配
predicates:- Host=**.some.com, nlog.daxuesoutijiang.com
Method匹配請求的獲取方法 Get Post??
predicates:- Method=Get,Post
Path匹配url的路徑
predicates:- Path=/getServer/**
Query匹配url的查詢參數? 后面的參數,需要一個param,和可選的正則表達式regexp?
?hhh=ww
predicates:- Query=hhh, ww
RemoteAddr

匹配的是請求的遠程地址

192.168.0.1是ip地址,/16是子網掩碼,表示

匹配的是192.168.0.1 -?192.168.255.255

predicates:- RemoteAddr=192.168.0.1/16
Weight將請求分流,如果有請求滿足了weight_high和weight_low的規則,那么就會根據weight的權重來進行分配到那個服務中進行,這里是通過相同的權重key(group1)來進*行權重的劃分的?
- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8
- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2

192.168.0.1這后面的.0.1拆開其實是 00000000.00000001 8為二進制,16表示從有往左的16為是網絡為那么就對應的這一段地址 192.168.0.1 - 192.168.255.255

Gateway Filter Factory 網關過濾器工廠

predicate決定了請求要經過那個路由處理,如果要對請求進行加工的話就要是使用Filter了

AddRequestParameter

再url中添加字段,最終到url上是

127.0.0.1:8080/hh?hh=ww&www=hhh

這時多個參數的寫法

filters:- AddRequestParameter=hh,wwAddRequestParameter=www,hhh
AddRequestHeader再請求頭中添加字段h=h1
filters:- AddRequestHeader=h,h1
AddResponseHeader再響應頭中添加字段
filters:- AddResponseHeader=r1,h1
RemoveRequestHeader刪除請求頭的某個字段
filters:- RemoveRequestHeader=del
RemoveResponseHeader刪除響應頭的某個字段
filters:- emoveResponseHeader=del
RequestSize限制請求的最大大小單位字節,默認5M
filters:- name: RequestSizeargs:maxSize: 50000000

Retry

若后端響應失敗會重試3次,Retry還支持很多其他的參數, 比如

methord:應該初始的http方法,用org.springframework.http.HttpMethod表示

status:要重試的狀態代碼,org.springframework.http.HttpStatus這個類來表示的

series:要重試的狀態代碼系列,用?org.springframework.http.HttpStatus.Series表示

exceptions:后端拋出異常的類型要重試

還有個backoff可以去原文檔看

如果使用了Retry,他的默認配置是

  • retries: 三次

  • series: 5XX系列

  • methods: GET 請求

  • exceptions:?IOException?和?TimeoutException

  • backoff: disabled

filters:- name: Retryargs:retries: 3statuses: BAD_GATEWAY

RequestRateLimiter

對請求的流量進行限制,若請求被限流則會返回

HTTP 429 - Too Many Requests

使用的是令牌桶算法來限流,需要配置一個KeyResolver類型的bean,他會根據請求的類型來算出一個key,然后通過這個key來獲取到一個令牌桶,所以RequestRateLimiter是通過某種規則來對同種類型(相同key)的請求進行限流,而不是全局限流

使用的時候需要加入依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency> 實現KeyResolver方法@Bean
KeyResolver ipKeyResolver() {return exchange -> {return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());};
}

這個方法會將請求的ip當作key

filters:- name: RequestRateLimiterargs:redis-rate-limiter.burstCapacity: 20redis-rate-limiter.replenishRate: 12redis-rate-limiter.requestedTokens: 1key-resolver: "#{@ipKeyResolver}" # 這個就對應了實現的KeyResolver bean

redis-rate-limiter.replenishRate 這個代表的是每秒鐘允許多少個請求,每秒鐘往令牌桶中添加的令牌數

redis-rate-limiter.burstCapacity 每秒鐘能允許的最大的令牌數,令牌桶的最大容量

redis-rate-limiter.requestedTokens 每次請求消耗的令牌數

這里的name表示的是要加入哪個過濾器,args中的是參數

Defualt Filters

之前設置的filter只對當前路由生效,而如果想要使Filter對所有的路由生效就可以添加

spring.cloud.gateway.default-filters屬性

spring:cloud:gateway:?     default-filters:- AddRequestParameter=p1,p1

GlobalFilter 全局過濾

GlobalFilter是gateway的全局過濾器,他和GatewayFilter的作用是相同的,他會應用到全局路由中,通常用于實現與安全性,性能檢測,日志打印相關聯的全局功能

查看GlobalFilter的監控信息

引入依賴

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

添加一些配置文件

spring:cloud:gateway:# 開啟了一些指標信息的搜集 請求計數 耗時什么的metrics:enabled: true
management:#  暴露所有 Actuator 端點 這樣就鞥看到更詳細的監控端口endpoints:web:exposure:include: "*"endpoint:# 更詳細的健康信息health:show-details: always# 允許遠程關閉服務 調用actuator/shutdown發起post請求shutdown:enabled: true

訪問127.0.0.1:8080/actuator?就可以看到詳細的監控信息了

當然不添加剛剛哪些配置文件也能訪問

過濾器的執行順序

當配置了global filter和gateway filter之后,網關會把他們合并到一個集合鏈中來以此執行,每一個過濾器都必須指定一個int值,值越小的優先級越高越先執行,filter通過實現order接口或者添加@order注解來決定int值

對于spring cloud filter的過濾器由spring來決定

用戶自定義的過濾器由用戶自己決定

當order的值相同時,會按照default filter -> gateway filter? -> global filter順序執行

自定義gateway filter

要自定義filter,那么就需要實現GatewayFilterFactory接口,spring提供了一個實現了GatewayFilterFactory的抽象類,我們只需要實現過濾邏輯和優先級就好

@Service
public class CustomizeGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomizeConfig> implements Ordered {public CustomizeGatewayFilterFactory() {super(CustomizeConfig.class);}@Overridepublic GatewayFilter apply(CustomizeConfig config) {return  ((exchange, chain) -> {log.info("request url" + exchange.getRequest().getURI() + "  " + config.toString());return chain.filter(exchange);}));});}@Overridepublic int getOrder() {return HIGHEST_PRECEDENCE;}
}

這個過濾器會把請求的url打印出來

如果請求通過的話,就把請求傳遞到下一個斷言 return chain.filter(exchange)

如果不通過那么可以這樣直接拒絕?return exchange.getResponse().setComplete()

也可以把通過過濾器的url打印出來

            return chain.filter(exchange).then(Mono.defer(() -> {//這樣獲取到的是原來的url,因為這個ServerHttpRequest是不可以修改的,要獲取到最后的url需要重新獲取到ServerHttpRequest對象log.info("end origin: {}", exchange.getRequest().getURI());URI routedUri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);log.info("end routed: {}", routedUri);return Mono.empty();}));

自定義 全局過濾器 glocal filter

只需要實現GlobalFilter接口就號

@Service
@Slf4j
public class CustomizeGlobalFiler implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(exchange.getRequest().getURI().toString());  return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE;}
}

和gateway 實現很相似

end ~~

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

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

相關文章

返利app的消息隊列架構:基于RabbitMQ的異步通信與解耦實踐

返利app的消息隊列架構&#xff1a;基于RabbitMQ的異步通信與解耦實踐 大家好&#xff0c;我是阿可&#xff0c;微賺淘客系統及省賺客APP創始人&#xff0c;是個冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在返利app的業務流程中&#xff0c;用戶下單、返利計算…

Vue3 響應式失效 debug:Proxy 陷阱導致數據更新異常的深度排查

人們眼中的天才之所以卓越非凡&#xff0c;并非天資超人一等而是付出了持續不斷的努力。1萬小時的錘煉是任何人從平凡變成超凡的必要條件。———— 馬爾科姆格拉德威爾 &#x1f31f; Hello&#xff0c;我是Xxtaoaooo&#xff01; &#x1f308; “代碼是邏輯的詩篇&#xff0…

【貪心算法】day10

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的貪心算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&#xff…

LeetCode算法日記 - Day 42: 島嶼數量、島嶼的最大面積

目錄 1. 島嶼數量 1.1 題目解析 1.2 解法 1.3 代碼實現 2. 島嶼的最大面積 2.1 題目解析 2.2 解法 2.3 代碼實現 1. 島嶼數量 https://leetcode.cn/problems/number-of-islands/ 給你一個由 1&#xff08;陸地&#xff09;和 0&#xff08;水&#xff09;組成的的二維…

短波紅外相機在機器視覺檢測方向的應用

短波紅外相機在機器視覺檢測方向的應用短波紅外相機&#xff1a;機器視覺的“低成本突破者”一、打破成本困局&#xff1a;短波紅外的“平民化”革新二、核心技術&#xff1a;有機材料的“硬核創新”1. 材料革命&#xff1a;有機感光層的優勢2. 工藝兼容&#xff1a;嫁接成熟CM…

【數據結構與算法】圖 Floyd算法

相關題目&#xff1a; 1334. 閾值距離內鄰居最少的城市 - 力扣&#xff08;LeetCode&#xff09; 資料 &#xff1a; Floyd算法原理及公式推導 - 知乎 Floyd 算法是一種經典的動態規劃算法&#xff0c;用與求解圖中所有頂點之間的最短短路路徑。它由Robert Floyd 于1962…

衛星通信天線的指向精度,含義、測量和計算

衛星通信天線的指向精度&#xff0c;含義、測量和計算我們在衛星通信天線的技術規格書中&#xff0c;都會看到天線指向精度這個指標。一般來說&#xff0c;技術規格書上的天線指向精度的參數是這么寫的&#xff1a;“天線指向精度≤1/10半功率波束帶寬”今天這個文章&#xff0…

基于LSTM與3秒級Tick數據的金融時間序列預測實現

數據加載模塊解析 def load_data(filepath):df pd.read_csv(filepath)return df該函數承擔基礎數據采集職責&#xff0c;通過Pandas庫讀取CSV格式的高頻交易數據&#xff08;典型如股票分筆成交明細&#xff09;。輸入參數為文件路徑字符串&#xff0c;輸出結構化DataFrame對象…

C# --- Field and Property

C# --- Field and Property字段 (Field) vs. 屬性 (Property)Property的聲明初始化方法單例類property錯誤初始化導致線程泄漏字段 (Field) vs. 屬性 (Property) 字段 (Field) - 數據的存儲容器 字段是直接在類或結構中聲明的變量。它是存儲數據的地方&#xff0c;是對象狀態的…

【Python】實現一個文件夾快照與比較工具

1. 工具簡介 在日常開發、項目管理或備份場景中&#xff0c;我們經常需要知道某個文件夾中的文件是否發生變化&#xff0c;例如&#xff1a; 項目源碼是否新增或修改文件&#xff1f;數據集是否被不小心刪除或篡改&#xff1f;備份文件夾是否和上次一致&#xff1f; 本教程將教…

LINUX913 shell:set ip [lindex $argv 0],\r,send_user,spawn ssh root@ip “cat “

問題 獲取公鑰 [codesamba ~]$ cat pub.sh #!/bin/usr/expect set ip "$1" set password 123456 set timeout 20 spawn ssh root192.168.235.100:cat ~/.ssh/id_rsa.pub expect { "yes/no" {send "yes/r";exp_continue} "password:" {…

Acwing算法基礎課--鏈表

一、單鏈表 AcWing 826. 單鏈表 代碼 N 100010 idx 0 e [0] * N ne [0] * N head -1def init():global idx,headidx 0head -1def add_head(x):global idx,heade[idx] xne[idx] headhead idxidx 1def delete(k):ne[k] ne[ne[k]]def add_k(k,x):global idxe[idx] …

AI表征了西方的有界,AI+體現了東方的無界

AI表征了西方的有界&#xff0c;AI體現了東方的無界&#xff0c;試圖通過文化差異的視角來對比傳統AI&#xff08;AI&#xff09;與增強型或融合型AI&#xff08;AI&#xff09;的特征。一、“AI表征了西方的有界”西方的“有界”可以理解為&#xff1a;1、邏輯清晰、結構嚴謹&…

LabVIEW泵輪檢測

?在現代制造業蓬勃發展的浪潮下&#xff0c;汽車行業也迎來了高速發展期。液力變矩器作為實現車輛自動變速的關鍵零件產品&#xff0c;在汽車動力系統中扮演著不可或缺的角色。泵輪作為液力變矩器的核心組成部分&#xff0c;其生產質量直接影響著液力變矩器的性能。因此&#…

RT-DETRv2 中的坐標回歸機制深度解析:為什么用 `sigmoid(inv_sigmoid(ref) + delta)` 而不是除以圖像尺寸?

引言&#xff1a;一個看似簡單的公式&#xff0c;背后藏著工業級設計智慧 在閱讀 RT-DETRv2&#xff08;Real-Time DETR v2&#xff09;源碼時&#xff0c;我曾被一行代碼深深震撼&#xff1a; inter_ref_bbox F.sigmoid(bbox_head[i](output) inverse_sigmoid(ref_points_de…

簡單了解一下GraphRAG

傳統RAG的缺點 當我們將一段文本信息以句子分割后&#xff0c;存入到向量數據庫中。用戶提問“老王喜歡吃什么”&#xff0c;這個問題會與向量數據庫中的許多句子關聯性比較強&#xff0c;能返回準確且具體的信息。 但是&#xff0c;若是問題換成“出現了幾次西瓜”&#xff0c…

HTTP 狀態碼背后的邏輯:從請求到響應的完整流程解析(含完整流程圖)

在日常的 Web 開發與 API 調試中&#xff0c;我們經常會遇到各種 HTTP 狀態碼 ——404 Not Found、401 Unauthorized、500 Internal Server Error... 這些數字背后并非隨機出現&#xff0c;而是服務器處理請求過程中不同階段的 "反饋信號"。理解這些狀態碼的觸發邏輯…

Vue:下拉框多選影響行高

目錄 一、 出現場景二、 解決方案 一、 出現場景 在使用el-select增加multiple屬性進行多選時&#xff0c;會出現高度塌陷的情況 二、 解決方案 首先需要在el-select中增加collapse-tags屬性&#xff0c;并在style中增加如下樣式 方案一 <style scoped> ::v-deep .e…

如何在高通躍龍QCS6490 Arm架構上使用Windows 11 IoT企業版?

1.簡介研華已將高通躍龍QCS6490 技術應用于嵌入式模塊、單板電腦和AI攝像頭等各種規格的嵌入式硬件中。QCS6490平臺支持全面的操作系統生態系統&#xff0c;包括Windows、Ubuntu、Yocto和 Android。Windows 11 IoT企業版是微軟新一代的物聯網操作系統&#xff0c;具有更強的安全…

阿里云國際代理:如何利用RDS構建高可用、可擴展的數據庫架構

講下云數據庫RDS案例解析&#xff0c;若在上云或用云過程中有不懂的&#xff0c;可尋云樞國際yunshuguoji助力免卡上云用云。1、RDS MySQL數據庫代理支持讀寫分離、連接保持、就近訪問、事務拆分、連接池、SSL加密等功能&#xff0c;能夠降低主實例負載&#xff0c;提高實例可用…