Java實戰:Spring Boot項目中如何利用Redis實現用戶IP接口限流

引言

在高并發的Web應用中,接口限流是一項至關重要的技術手段,它有助于保護系統資源,防止因瞬間流量高峰導致服務崩潰。本文將深入探討如何在Spring Boot項目中借助Redis實現用戶IP級別的接口限流策略,通過具體的代碼示例,詳細介紹其設計思路與實現過程。

一、限流策略與Redis選擇

  1. 限流策略

    常見的限流算法有令牌桶(Token Bucket)、漏桶(Leaky Bucket)和滑動窗口(Sliding Window)。在用戶IP級別限流中,我們可以選擇基于Redis的鍵值存儲特性,結合Lua腳本,實現滑動窗口算法的限流策略,兼顧靈活性和高性能。

  2. 為何選擇Redis

    Redis作為一款高性能的內存型數據庫,具備優秀的數據結構和原子操作能力,非常適合用于限流場景。其鍵過期機制可以輕松實現限流窗口期的設定,同時,通過Redis的lua腳本支持,可以原子化地進行讀寫操作,確保限流邏輯的準確性。

二、Spring Boot集成Redis

  1. 添加Redis依賴

    在Spring Boot項目中,通過引入spring-boot-starter-data-redis依賴,方便地集成Redis:

    <!-- Maven -->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置Redis連接

    application.propertiesapplication.yml中配置Redis連接信息:

    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    

三、基于Redis實現用戶IP限流

  1. 限流Key設計

    為每個用戶IP設置唯一的限流Key,格式如下:

    rate_limit:ip:<用戶IP>:<接口名>
    
  2. Lua腳本設計

    編寫Lua腳本來實現滑動窗口限流邏輯,該腳本的主要功能是檢查指定IP在最近N秒內對特定接口的訪問次數,如果超過預設閾值,則拒絕請求。

    -- lua-script.lua
    local key = KEYS[1] -- 用戶IP限流key
    local limit = tonumber(ARGV[1]) -- 訪問次數閾值
    local window = tonumber(ARGV[2]) -- 時間窗口(單位:秒)local current_timestamp = redis.call('TIME')[1]
    local requests = redis.call('ZRANGEBYSCORE', key, current_timestamp - window, '+inf')if #requests >= limit thenreturn 0 -- 限流
    endredis.zadd(key, current_timestamp, current_timestamp)
    return 1 -- 允許請求
    
  3. Spring Boot限流服務實現

    創建一個限流服務,封裝限流邏輯,并在AOP中實現攔截與限流判定:

    @Service
    public class RateLimiterService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public boolean isAllowed(String ip, String apiName, int limit, int windowSeconds) {DefaultRedisScript<Boolean> script = new DefaultRedisScript<>(new ClassPathResource("lua-script.lua"), Boolean.class);script.setNumKeys(1);List<String> keys = Collections.singletonList("rate_limit:ip:" + ip + ":" + apiName);List<Object> args = Arrays.asList(limit, windowSeconds);Boolean allowed = redisTemplate.execute(script, keys, args);return allowed != null && allowed;}
    }@Aspect
    @Component
    public class RateLimitAspect {@Autowiredprivate RateLimiterService rateLimiterService;@Around("@annotation(com.example.RateLimited)")public Object around(ProceedingJoinPoint pjp) throws Throwable {MethodSignature signature = (MethodSignature) pjp.getSignature();RateLimited rateLimited = signature.getMethod().getAnnotation(RateLimited.class);HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String ip = request.getHeader("X-Real-IP");if (!rateLimiterService.isAllowed(ip, signature.getMethod().getName(), rateLimited.limit(), rateLimited.window())) {throw new ApiException(HttpStatus.TOO_MANY_REQUESTS, "請求過于頻繁,請稍后再試!");}return pjp.proceed();}
    }
    

    注:RateLimited是一個自定義的注解,用于標記需要限流的接口方法。

四、優化與擴展

  1. 自定義注解與限流策略

    可以根據業務需求,創建不同的限流注解,并在注解中定義不同的限流策略,如全局限流、用戶ID限流等。

  2. 降級策略

    當達到限流閾值時,除了拒絕請求外,還可以采取降級策略,如返回默認數據、進入等待隊列、發送警告通知等。

  3. 分布式限流

    在分布式環境下,需要考慮分布式鎖或Redlock機制,確保限流邏輯的一致性。

五、結論

通過本文,我們了解了如何在Spring Boot項目中利用Redis實現用戶IP級別的接口限流,從限流策略的設計、Redis的集成、Lua腳本的編寫到最終的AOP攔截,形成了一套完整的解決方案。在實際項目中,應根據具體需求靈活調整限流策略,并結合其他手段如熔斷、降級等,構建健壯的高并發服務體系。

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

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

相關文章

大數據概述

學習大數據有什么用&#xff1f; 2010年&#xff1a;大數據技術體系開始在國內火熱 2015年&#xff1a;國務院印發《促進大數據發展行動綱要》 2016年&#xff1a;發改委發布關于組織實施促進大數據發展重大工程的通知 2017年&#xff1a;工信部印發大數據產業規劃(2016-20…

Linux運維_Bash腳本_構建安裝Meson-1.0.1和Ninja-1.11.1

Linux運維_Bash腳本_構建安裝Meson-1.0.1和Ninja-1.11.1 Bash (Bourne Again Shell) 是一個解釋器&#xff0c;負責處理 Unix 系統命令行上的命令。它是由 Brian Fox 編寫的免費軟件&#xff0c;并于 1989 年發布的免費軟件&#xff0c;作為 Sh (Bourne Shell) 的替代品。 您…

Nginx高級技巧:實現負載均衡和反向代理

文章目錄 Nginx概述Nginx作用正向代理反向代理負載均衡動靜分離 Nginx的安裝 -->Docker3.1 安裝Nginx3.2 Nginx的配置文件3.3 修改docker-compose文件 Nginx源碼安裝nginx常用命令nginx配置文件配置文件位置配置文件結構詳情 Nginx的反向代理【重點】基于Nginx實現反向代理4…

C語言冒泡排序(高級版)

目錄: 冒泡排序的原理 主函數 "冒泡排序函數" 比較函數 交換函數 最終輸出 完整代碼 冒泡排序的原理: 冒泡排序的原理是&#xff1a;從左到右&#xff0c;相鄰元素進行比較。每次比較一輪&#xff0c;就會找到序列中最大的一個或最小的一個。這個數就會從序列的最右…

Windows上構建一個和Linux類似的Terminal

preview 目的是在Windows上構建一個和Linux類似的Terminal&#xff0c;讓Windows煉丹和Linux一樣舒適&#xff0c;同是讓Terminal取代Xshell完成遠程鏈接。 預覽如下圖 在Linux下我們使用zsh和oh-my-zsh結合&#xff0c;Windows下我們使用powershell7和oh-my-posh結合。 前提…

Vue 前端開發 v-for和v-if兩個指令不能混合使用

原由&#xff1a; 在進行項目開發的時候因為在一個標簽上同時使用了v-for和v-if兩個指令導致的報錯。 提示錯誤&#xff1a;The undefined variable inside v-for directive should be replaced with a computed property that returns filtered array instead. You should no…

nginx------------緩存功能 ip透傳 負載均衡 (六)

一、http 協議反向代理 &#xff08;一&#xff09;反向代理示例:緩存功能 緩存功能可以加速訪問&#xff0c;如果沒有緩存關閉后端服務器后&#xff0c;圖片將無法訪問&#xff0c;緩存功能默認關閉&#xff0c;需要開啟。 ? proxy_cache zone_name | off; 默認off #指明調…

基于Springboot純凈水配送和商城系統設計與實現 開題報告參考

博主介紹&#xff1a;黃菊華老師《Vue.js入門與商城開發實戰》《微信小程序商城開發》圖書作者&#xff0c;CSDN博客專家&#xff0c;在線教育專家&#xff0c;CSDN鉆石講師&#xff1b;專注大學生畢業設計教育和輔導。 所有項目都配有從入門到精通的基礎知識視頻課程&#xff…

2023 版王道單科書勘誤匯總(3.30)

注:因2023版對題目編號做了優化“歷年真題全部放最后、且按年份排序”&#xff0c;以方便大家根據需要保留某些年份的真題作為最后的模擬。所以造成了一些題目和解析的編號錯誤。 數據結構: P11 P20 P56 P278 P326 “2.”中第 3 行”題 5改成”9”&#xff0c;第6行”題 8”改成…

css3詳解

一.什么是CSS3 CSS3是Cascading Style Sheets的第三個版本&#xff0c;是一種用于描述文檔樣式的語言&#xff08;CSS3是CSS&#xff08;層疊樣式表&#xff09;技術的升級版本&#xff09;。它是前端開發中用于控制網頁布局和樣式的技術之一。CSS3引入了許多新的特性和功能&a…

Linux常用操作命令大全

Linux常用操作命令大全 Linux,作為一款開源的操作系統,深受全世界開發者和系統管理員的喜愛。在Linux環境下,用戶通過命令行界面可以執行各種操作,從而實現對系統的全面控制。本文將詳細介紹Linux中常用的操作命令,幫助讀者更好地理解和運用這些命令。 一、文件操作命令…

hexo圖片顯示不出且圖片路徑錯誤/.com//

參考博客&#xff1a; hexo 圖片顯示問題及使用typora設置圖片路徑-CSDN博客 javascript - hexo 圖片路徑錯誤/.com// - SegmentFault 思否 先說如何讓hexo圖片成功地顯示出來 Step1: 修改config設置 將 _config.yml 設置文件中的 post_asset_folder 修改為 true 這一步的作…

平衡二叉樹,二叉樹的路徑,左葉子之和

第六章 二叉樹part04 今日內容&#xff1a; 110.平衡二叉樹 257. 二叉樹的所有路徑 404.左葉子之和 110.平衡二叉樹 &#xff08;優先掌握遞歸&#xff09; 給定一個二叉樹&#xff0c;判斷它是否是高度平衡的二叉樹。 本題中&#xff0c;一棵高度平衡二叉樹定義為&am…

【不可不知的考研復試秘籍 1】

----------------------------------------------------------------------------------------------------- 考研復試科研背景提升班 教你快速深入了解掌握考研復試面試中的常見問題以及注意事項&#xff0c;系統的教你如何在短期內快速提升自己的專業知識水平和編程以及英語…

windows下安裝cnpm

cnpm是淘寶團隊開發的一個針對中國用戶的npm鏡像源&#xff0c;它是npm的一個定制版本。由于國外的npm源在國內訪問速度較慢&#xff0c;所以cnpm鏡像源可以提供更快的下載速度。cnpm的使用方式與npm基本相同&#xff0c;只需將npm替換為cnpm即可。 要想使用cnpm等先安裝node.…

反序列化逃逸 [安洵杯 2019]easy_serialize_php1

打開題目 題目源碼&#xff1a; <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…

每日一題 KY148還是暢通工程

某省調查鄉村交通狀況&#xff0c;得到的統計表中列出了任意兩村莊間的距離。省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通&#xff08;但不一定有直接的公路相連&#xff0c;只要能間接通過公路可達即可&#xff09;&#xff0c;并要求鋪設的公路總長度…

PostgreSQL對已有表增加自增序列

對已有表增加自增序列&#xff1a; 1、在PostgreSQL當中&#xff0c;我們要實現對已有表的ID字段自增。 首先需創建一個關聯序列&#xff0c;以下sql語句是創建一個序列&#xff1a; CREATE SEQUENCE menu_id_seq START 6000001; 序列名稱是menu_id_seq&#xff0c;起始…

sizeof 和 strlen的區別

sizeof sizeof是單目操作符,sizeof計算變量所棧內存空間大小,單位是字節,如果操作數是類型的話,會計算類型所占大小,sizeof指在乎占用內存空間大小不在乎內容是什么. int main() {int a 0;printf("%zd\n", sizeof(a));printf("%zd\n", sizeof a );printf…

巧【二叉搜索樹的最近公共祖先】【二叉搜索樹的性質】Leetcode 235. 二叉搜索樹的最近公共祖先

【二叉搜索樹的最近公共祖先】【二叉搜索樹性質】Leetcode 235. 二叉搜索樹的最近公共祖先 【巧】解法1 利用二叉搜索樹有序的性質解法2 采用二叉樹求最近公共祖先的方法——后序遍歷 ---------------&#x1f388;&#x1f388;235. 二叉搜索樹的最近公共祖先 題目鏈接&#x…