Spring Cloud Gateway高并發限流——基于Redis實現方案解析

本文是一個基于 Spring Cloud Gateway 的分布式限流方案,使用Redis +
Lua實現高并發場景下的精準流量控制。該方案支持動態配置、多維度限流(API路徑/IP/用戶),并包含完整的代碼實現和性能優化建議。


一、架構設計

限流過濾器
動態推送
放行
攔截
客戶端
Spring Cloud Gateway
Redis集群
限流規則配置中心
微服務
返回429狀態碼

二、核心代碼實現

  1. 自定義限流過濾器
@Component
public class RedisRateLimitFilter implements GlobalFilter, Ordered {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Autowiredprivate RateLimitConfigService configService;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 獲取限流配置(根據請求路徑動態獲取)Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);RateLimitRule rule = configService.getRule(route.getId());// 生成限流Key(示例:api_limit:/order:create:ip:192.168.1.1)String key = buildRateLimitKey(exchange, rule);// 執行Lua腳本boolean allowed = evalLuaScript(key, rule);if (allowed) {return chain.filter(exchange);} else {exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);return exchange.getResponse().setComplete();}}private String buildRateLimitKey(ServerWebExchange exchange, RateLimitRule rule) {return String.join(":","api_limit",exchange.getRequest().getPath().value(),rule.getType(), // 限流維度:ip/user/apigetIdentifier(exchange, rule) // 獲取標識(IP/用戶ID等));}
}
  1. 高性能Lua腳本(rate_limiter.lua
local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])local fill_time = capacity / rate
local ttl = math.floor(fill_time * 2)local last_tokens = tonumber(redis.call("get", tokens_key) or capacity)
local last_refreshed = tonumber(redis.call("get", timestamp_key) or 0)local delta = math.max(0, now - last_refreshed)
local filled_tokens = math.min(capacity, last_tokens + (delta * rate))local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
if allowed thennew_tokens = filled_tokens - requested
endredis.call("setex", tokens_key, ttl, new_tokens)
redis.call("setex", timestamp_key, ttl, now)return allowed and 1 or 0
  1. 腳本執行器
public boolean evalLuaScript(String key, RateLimitRule rule) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptSource(new ResourceScriptSource(new ClassPathResource("rate_limiter.lua")));script.setResultType(Long.class);List<String> keys = Arrays.asList(key + ":tokens", key + ":timestamp");String rate = String.valueOf(rule.getRate());  // 每秒生成令牌數String capacity = String.valueOf(rule.getBurstCapacity()); // 桶容量String now = String.valueOf(System.currentTimeMillis() / 1000); // 當前秒級時間戳String requested = String.valueOf(rule.getRequestedTokens()); // 每次請求消耗令牌數Long result = redisTemplate.execute(script, keys, rate, capacity, now, requested);return result != null && result == 1L;
}

三、動態規則配置

  1. 規則實體類
@Data
public class RateLimitRule {private String routeId;       // 路由IDprivate String type;          // 限流維度:IP/USER/APIprivate int burstCapacity;   // 桶容量(突發流量)private double rate;          // 令牌生成速率/秒private int requestedTokens = 1; // 每次請求消耗令牌數
}
  1. 配置中心監聽
@RefreshScope
@Component
public class RateLimitConfigService {private Map<String, RateLimitRule> ruleMap = new ConcurrentHashMap<>();@Autowiredprivate NacosConfigManager nacosConfigManager;@PostConstructpublic void init() {// 監聽Nacos配置變化nacosConfigManager.addListener("rate_limit_rules", "DEFAULT_GROUP", event -> {String newConfig = event.getConfig().getContent();updateRules(JSON.parseObject(newConfig, new TypeReference<List<RateLimitRule>>() {}));});}private void updateRules(List<RateLimitRule> newRules) {ruleMap = newRules.stream().collect(Collectors.toConcurrentMap(RateLimitRule::getRouteId, Function.identity()));}
}

四、性能優化策略

  1. Redis連接優化
# application.yml
spring:redis:lettuce:pool:max-active: 200      # 最大連接數max-idle: 50min-idle: 20timeout: 3000
  1. 本地緩存降級
public class RateLimitFilter {// 使用Guava Cache做本地限流降級private LoadingCache<String, Boolean> localCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.SECONDS).build(new CacheLoader<String, Boolean>() {@Overridepublic Boolean load(String key) {return true; // 默認允許訪問}});public boolean checkLocalCache(String key) {try {return localCache.get(key);} catch (ExecutionException e) {return true;}}
}
  1. 監控埋點
@Autowired
private MeterRegistry meterRegistry;public boolean evalLuaScript(String key, RateLimitRule rule) {Timer.Sample sample = Timer.start(meterRegistry);boolean allowed = ...;sample.stop(meterRegistry.timer("rate.limit.time", "route", rule.getRouteId()));Counter.builder("rate.limit.requests").tag("route", rule.getRouteId()).tag("allowed", String.valueOf(allowed)).register(meterRegistry).increment();return allowed;
}

五、壓測數據對比

測試環境
? 網關節點:4C8G × 3

? Redis集群:6節點(3主3從)

? 壓測工具:wrk 10萬并發連接

性能指標

場景QPS平均延遲錯誤率
無限流28,00035ms0%
單節點限流19,50048ms0%
Redis集群限流15,20063ms0.05%
限流+本地緩存降級17,80055ms0.3%

六、方案對比

限流方案優點缺點
Redis令牌桶(本方案)精準分布式控制增加Redis依賴
網關內置限流(如Sentinel)開箱即用擴展性受限
Nginx限流高性能無法動態更新規則

七、部署建議

  1. Redis集群化:至少3主節點保障高可用

  2. 網關節點擴容:配合K8s HPA根據CPU使用率自動擴縮容

  3. 監控告警:
    ? Redis內存使用率 >80%

    ? 網關節點線程池活躍度 >90%

    ? 限流拒絕率連續5分鐘 >10%


該方案已在多個千萬級DAU的電商系統中驗證,可支撐每秒2萬+的限流判斷請求,端到端延遲控制在5ms以內。

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

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

相關文章

SpringAI--RAG知識庫

SpringAI–RAG知識庫 RAG概念 什么是RAG&#xff1f; RAG(Retrieval-Augmented Genreation&#xff0c;檢索增強生成)是一種結合信息檢索技術和AI內容生成的混合架構&#xff0c;可以解決大模型的知識時效性限制和幻覺問題。 RAG在大語言模型生成回答之前&#xff0c;會先從…

【PhysUnits】14 二進制數的標準化表示(standardization.rs)

一、源碼 這段代碼主要用于處理二進制數的標準化表示。它定義了兩個特質(trait) IfB0 和 IfB1&#xff0c;以及它們的實現&#xff0c;用于處理二進制數的前導零及前導一的簡化。 use super::basic::{B0, B1, Z0, N1, Integer, NonZero, NonNegOne};/// 處理 B0<H> 類型…

將 ubutun 的網絡模式 從NAT 改到 橋接模式后,無法上網,linux 沒有IP地址 的解決方案

首先要將 ubutun 的網絡模式設置為橋接模式 這里再從 NAT 模式改動成 橋接模式的時候&#xff0c;還出現了一個問題。改成橋接模式后&#xff0c;linux沒有ip地址了。原因是 不知道什么時候 將 虛擬網絡編輯器 中的值改動了 要選擇這個 自動 選項

多模態大語言模型arxiv論文略讀(九十)

Hybrid RAG-empowered Multi-modal LLM for Secure Data Management in Internet of Medical Things: A Diffusion-based Contract Approach ?? 論文標題&#xff1a;Hybrid RAG-empowered Multi-modal LLM for Secure Data Management in Internet of Medical Things: A Di…

電腦主板VGA長亮白燈

電腦主板VGA長亮白燈 起因解決方法注意事項&#xff1a; 起因 搬家沒有拆機整機在車上晃蕩導致顯卡松動接觸不良&#xff08;一般VGA長亮白燈都和顯卡有關&#xff0c;主要排查顯卡&#xff09; 解決方法 將顯卡拆下重新安裝即可 注意事項&#xff1a; 不可直接拔下顯卡&a…

【監控】pushgateway中間服務組件

Pushgateway 是 Prometheus 生態中的一個中間服務組件&#xff0c;以獨立工具形式存在&#xff0c;主要用于解決 Prometheus 無法直接獲取監控指標的場景&#xff0c;彌補其定時拉取&#xff08;pull&#xff09;模式的不足。 其用途如下&#xff1a; 突破網絡限制&#xff1…

打造AI智能旅行規劃器:基于LLM和Crew AI的Agent實踐

引言 今天來學習大佬開發的一個AI驅動的旅行規劃應用程序&#xff0c;它能夠自動處理旅行規劃的復雜性——尋jni找航班、預訂酒店以及優化行程。傳統上&#xff0c;這個過程需要手動搜索多個平臺&#xff0c;常常導致決策效率低下。 通過利用**代理型人工智能&#xff08;Age…

21. 自動化測試框架開發之Excel配置文件的測試用例改造

21. 自動化測試框架開發之Excel配置文件的測試用例改造 一、測試框架核心架構 1.1 組件依賴關系 # 核心庫依賴 import unittest # 單元測試框架 import paramunittest # 參數化測試擴展 from chap3.po import * # 頁面對象模型 from file_reader import E…

如何在電力系統中配置和管理SNTP時間同步?

在電力系統中配置和管理 SNTP 時間同步需結合行業標準&#xff08;如《DL/T 1100.1-2019》&#xff09;和分層架構特點&#xff0c;確保安全性、可靠性和精度適配。以下是具體操作指南&#xff0c;涵蓋架構設計、設備配置、安全管理、運維監控四大核心環節&#xff0c;并附典型…

MTK-關于HW WCN的知識講解

前言: 最近做項目過程中和硬件打交道比較多,現在關于整理下硬件的HW wcn的知識點 一 MTK常見的MT6631 Wi-Fi 2.4GHz 匹配調諧指南 ?拓撲結構選擇? 推薦采用并聯電容拓撲(?shunt cap topology?)代替并聯電感拓撲(?shunt inductor topology?),以減少潛在電路設計…

(1)課堂 1--5,這五節主要講解 mysql 的概念,定義,下載安裝與卸載

&#xff08;1&#xff09;謝謝老師&#xff1a; &#xff08;2&#xff09;安裝 mysql &#xff1a; &#xff08;3&#xff09;鏡像下載 &#xff0c;這個網址很好 &#xff1a; &#xff08;4&#xff09; 另一個虛擬機的是 zhang 123456 &#xff1a; 接著配置…

U-Boot ARMv8 平臺異常處理機制解析

入口點&#xff1a;arch/arm/cpu/armv8/start.S 1. 判斷是否定義了鉤子&#xff0c;如有則執行&#xff0c;否則往下走。執行save_boot_params&#xff0c;本質就是保存一些寄存器的值。 2. 對齊修復位置無關碼的偏移 假設U-Boot鏈接時基址為0x10000&#xff0c;但實際加載到0…

mysql安裝教程--筆記

一、Windows 系統安裝 方法1&#xff1a;使用 MySQL Installer&#xff08;推薦&#xff09; 1. 下載安裝包 訪問 MySQL 官網下載頁面&#xff0c;選擇 MySQL Installer for Windows。 2. 運行安裝程序 雙擊下載的 .msi 文件&#xff0c;選擇安裝類型&#xff1a; ? Developer…

投資策略規劃最優決策分析

目錄 一、投資策略規劃問題詳細 二、存在最優投資策略&#xff1a;每年都將所有錢投入到單一投資產品中 &#xff08;一&#xff09;狀態轉移方程 &#xff08;二&#xff09;初始條件與最優策略 &#xff08;三&#xff09;證明最優策略總是將所有錢投入到單一投資產品中…

NGINX HTTP/3 實驗指南安裝、配置與調優

一、HTTP/3 簡介 基于 QUIC&#xff1a;在 UDP 之上實現的多路復用傳輸&#xff0c;內置擁塞控制與前向糾錯&#xff0c;無需三次握手即可恢復連接。零 RTT 重連&#xff1a;借助 TLS 1.3&#xff0c;實現連接恢復時的 0-RTT 數據發送&#xff08;視底層庫支持&#xff09;。多…

編程日志5.28

string賦值操作 算法: #include<iostream> using namespace std; int main() { //1.字符串常量的賦值 string s1; s1 = "英雄哪里出來"; cout << s1 << endl; //2.字符串變量的賦值 string s2; s2 = s1; cout <…

AE的ai圖層導到Ai

AE的ai圖層導到ai 解決方法: 1、打開ai軟件&#xff0c;不用新建&#xff0c;留在那就行。 2、在AE里選中任意一個ai文件圖層&#xff0c;只需同時按住ctrl和英文字母鍵&#xff0c;圖層就會自動全部導入到ai中 英文字母鍵的詳情可以參考&#xff1a;http://www.yayihouse.co…

【Springboot+LangChain4j】Springboot項目集成LangChain4j(下)

前置條件&#xff1a;根據上篇文章完成springboot初步集成LangChain4j 【SpringbootLangChain4j】根據LangChain4j官方文檔&#xff0c;三分鐘完成Springboot項目集成LangChain4j&#xff08;上&#xff09;-CSDN博客 但是接口方法中&#xff0c;關于大模型的配置都是寫死的&a…

好壞質檢分類實戰(異常數據檢測、降維、KNN模型分類、混淆矩陣進行模型評估)

任務 好壞質檢分類實戰 task: 1、基于 data_class_raw.csv 數據&#xff0c;根據高斯分布概率密度函數&#xff0c;尋找異常點并剔除 2、基于 data_class_processed.csv 數據&#xff0c;進行 PCA 處理&#xff0c;確定重要數據維度及成分 3、完成數據分離&#xff0c;數據分離…

以少學習:通過無標簽數據從大型語言模型進行知識蒸餾

Learning with Less: Knowledge Distillation from Large Language Models via Unlabeled Data 發表&#xff1a;NNACL-Findings 2025 機構&#xff1a;密歇根州立大學 Abstract 在實際的自然語言處理&#xff08;NLP&#xff09;應用中&#xff0c;大型語言模型&#xff08…