Redis 限流

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessLimit {/*** 限制次數*/int count() default 15;/*** 時間窗口,單位為秒*/int seconds() default 60;
}
@Aspect
@Component
public class AccessLimitAspect {private static final String LUA_SCRIPT ="local key = KEYS[1] " +"local limit = tonumber(ARGV[1]) " +"local current = tonumber(redis.call('get', key) or '0') " +"if current + 1 > limit then " +"   return 0 " +"else " +"   redis.call('INCR', key) " +"   redis.call('EXPIRE', key, ARGV[2]) " +"   return 1 " +"end";private static final RedisScript<Long> SCRIPT_INSTANCE = new DefaultRedisScript<>(LUA_SCRIPT, Long.class);@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Before("@annotation(accessLimit)")public void checkAccessLimit(JoinPoint joinPoint, AccessLimit accessLimit) throws Throwable {validateAccessLimitParams(accessLimit);HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();String ipAddr = IpUtils.getIpAddr(request);String cacheKey = generateCacheKey(joinPoint, ipAddr);Long result = redisTemplate.execute(SCRIPT_INSTANCE,Collections.singletonList(cacheKey),accessLimit.count(),accessLimit.seconds());if (result != null && result == 0) {throw new RateLimitExceededException("操作過于頻繁,請稍后再試");}}private void validateAccessLimitParams(AccessLimit accessLimit) {if (accessLimit.count() <= 0 || accessLimit.seconds() <= 0) {throw new IllegalArgumentException("Invalid Access Limit parameters");}}private String generateCacheKey(JoinPoint joinPoint, String ipAddr) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();String methodName = signature.getMethod().getName();return TradeCachePrefix.ACCESS_LIMIT_PREFIX + methodName + "_" + ipAddr;}}

代碼邏輯

  1. 定義和初始化變量
    • key = KEYS[1]:從傳入的鍵列表中獲取第一個鍵,作為 Redis 中存儲計數器的鍵。
    • limit = tonumber(ARGV[1]):將傳入參數中的第一個值轉換為數字,這個值代表允許的最大請求次數(限制)。
    • current = tonumber(redis.call('get', key) or '0'):嘗試從 Redis 中獲取當前計數器的值。如果鍵不存在,使用默認值 '0'
  2. 判斷是否超出限制
    • if current + 1 > limit then: 檢查當前計數加一是否超過限制。
      • 如果超過限制,則返回 0,表示請求被拒絕。
  3. 更新計數器和設置過期時間
    • else: 如果沒有超過限制:
      • redis.call('INCR', key): 將計數器加一。
      • redis.call('EXPIRE', key, ARGV[2]): 設置該鍵的過期時間為傳入參數中的第二個值(秒)。
      • 返回 1,表示請求被接受。

應用場景

  • 限流機制:這個腳本通常用于實現基于 Redis 的限流功能。例如,在一定時間窗口內,只允許某個操作執行一定次數,以防止濫用。
  • API 請求限制:可以用于限制 API 的調用頻率,每個用戶或每個 IP 地址在特定時間內只能調用 API 一定次數。

使用方法

  • 執行腳本時需要傳遞兩個參數
    • 第一個參數是允許的最大請求次數(limit)。
    • 第二個參數是鍵的過期時間(單位為秒),即在多長時間內重置計數器。

通過這種方式,可以有效地控制訪問頻率,保護系統資源不被濫用。

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

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

相關文章

Android Coil3縮略圖、默認占位圖placeholder、error加載錯誤顯示,Kotlin(1)

Android Coil3縮略圖、默認占位圖placeholder、error加載錯誤顯示&#xff0c;Kotlin&#xff08;1&#xff09; implementation("io.coil-kt.coil3:coil-core:3.1.0")implementation("io.coil-kt.coil3:coil-network-okhttp:3.1.0") <uses-permission …

DeepSeek 助力 Vue 開發:打造絲滑的 鍵盤快捷鍵(Keyboard Shortcuts)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

uniapp引入uview組件庫(可以引用多個組件)

第一步安裝 npm install uview-ui2.0.31 第二步更新uview npm update uview-ui 第三步在main.js中引入uview組件庫 第四步在uni.scss中引入import "uview-ui/theme.scss"樣式 第五步在文件中使用組件

Jmeter進階篇(34)如何解決jmeter.save.saveservice.timestamp_format=ms報錯?

問題描述 今天使用Jmeter完成壓測執行,然后使用命令將jtl文件轉換成html報告時,遇到了報錯! 大致就是說jmeter里定義了一個jmeter.save.saveservice.timestamp_format=ms的時間格式,但是jtl文件中的時間格式不是標準的這個ms格式,導致無法正常解析。對于這個問題,有如下…

React 低代碼項目:網絡請求與問卷基礎實現

&#x1f35e;吐司問卷&#xff1a;網絡請求與問卷基礎實現 Date: February 10, 2025 Log 技術要點&#xff1a; HTTP協議XMLHttpRequest、fetch、axiosmock.js、postmanWebpack devServer 代理、craco.js 擴展 webpackRestful API 開發要點&#xff1a; 搭建 mock 服務 …

安裝海康威視相機SDK后,catkin_make其他項目時,出現“libusb_set_option”錯誤的解決方法

硬件&#xff1a;雷神MIX G139H047LD 工控機 系統&#xff1a;ubuntu20.04 之前運行某項目時&#xff0c;處于正常狀態。后來由于要使用海康威視工業相機&#xff08;型號&#xff1a;MV-CA013-21UC&#xff09;&#xff0c;便下載了并安裝了該相機的SDK&#xff0c;之后運行…

人工智能之自動駕駛技術體系

自動駕駛技術體系 自動駕駛技術是人工智能在交通領域的重要應用&#xff0c;旨在通過計算機視覺、傳感器融合、路徑規劃等技術實現車輛的自主駕駛。自動駕駛不僅能夠提高交通效率&#xff0c;還能減少交通事故和環境污染。本文將深入探討自動駕駛的技術體系&#xff0c;包括感…

淺談模組-相機鬼像

一&#xff0e;前言 在成像中&#xff0c;我們常常會遇到肉眼觀測的真實世界中&#xff0c;不存在的異常光影出現在畫面中&#xff0c;并伴有各種顏色&#xff0c;我們將這個物體稱為鬼像。某些鬼像可能會對圖像產生美感的體驗&#xff0c;但是大多數的鬼像都會對圖像的質量以…

vmware虛擬機Ubuntu Desktop系統怎么和我的電腦相互復制文件、內容

1、先安裝vmware workstation 17 player&#xff0c;然后再安裝Ubuntu Desktop虛擬機&#xff0c;然后再安裝vmware tools&#xff0c;具體可以參考如下視頻&#xff1a; VMware虛擬機與主機實現文件共享&#xff0c;其實一點也不難_嗶哩嗶哩_bilibili 2、本人親自試過了&…

Spring Boot項目中解決跨域問題(四種方式)

目錄 一&#xff0c;跨域產生的原因二&#xff0c;什么情況下算跨域三&#xff0c;實際演示四&#xff0c;解決跨域的方法 1&#xff0c;CrossOrigin注解2&#xff0c;添加全局過濾器3&#xff0c;實現WebMvcConfigurer4&#xff0c;Nginx解決跨域5&#xff0c;注意 開發項目…

Oracle JDK、Open JDK zulu下載地址

一、Oracle JDK https://www.oracle.com/java/technologies/downloads/ 剛進去是最新的版本&#xff0c;往下滑可以看到老版本 二、Open JDK的 Azul Zulu https://www.azul.com/downloads/ 直接可以選版本等選項卡

軟件測試:1、單元測試

1. 單元測試的基本概念 單元&#xff08;Unit&#xff09;&#xff1a;軟件系統的基本組成單位&#xff0c;可以是函數、模塊、方法或類。 單元測試&#xff08;Unit Testing&#xff09;&#xff1a;對軟件單元進行的測試&#xff0c;驗證代碼的正確性、規范性、安全性和性能…

Leetcode.264 丑數 II

題目鏈接 Leetcode.264 丑數 II mid 題目描述 給你一個整數 n n n &#xff0c;請你找出并返回第 n n n 個 丑數 。 丑數 就是質因子只包含 2 2 2、 3 3 3 和 5 5 5 的正整數。 示例1&#xff1a; 輸入&#xff1a;n 10 輸出&#xff1a;12 解釋&#xff1a;[1, 2, 3,…

瑞芯微RV1126部署YOLOv8全流程:環境搭建、pt-onnx-rknn模型轉換、C++推理代碼、錯誤解決、優化、交叉編譯第三方庫

目錄 1 環境搭建 2 交叉編譯opencv 3 模型訓練 4 模型轉換 4.1 pt模型轉onnx模型 4.2 onnx模型轉rknn模型 4.2.1 安裝rknn-toolkit 4.2.2 onn轉成rknn模型 5 升級npu驅動 6 C++推理源碼demo 6.1 原版demo 6.2 增加opencv讀取圖片的代碼 7 交叉編譯x264 ffmepg和op…

【Python爬蟲(32)】從單飛 to 團戰:Python多線程爬蟲進化史

【Python爬蟲】專欄簡介&#xff1a;本專欄是 Python 爬蟲領域的集大成之作&#xff0c;共 100 章節。從 Python 基礎語法、爬蟲入門知識講起&#xff0c;深入探討反爬蟲、多線程、分布式等進階技術。以大量實例為支撐&#xff0c;覆蓋網頁、圖片、音頻等各類數據爬取&#xff…

C#初級教程(1)——C# 與.NET 框架:探索微軟平臺編程的強大組合

圖片來源&#xff1a; https://www.lvhang.site/docs/dotnettimeline 即夢AI - 一站式AI創作平臺 一、歷史發展脈絡 在早期的微軟平臺編程中&#xff0c;常用的編程語言有 Visual Basic、C、C。到了 20 世紀 90 年代末&#xff0c;Win32 API、MFC&#xff08;Microsoft Found…

【接口封裝】——13、登錄窗口的標題欄內容設置

解釋&#xff1a; 1、封裝內容&#xff1a;圖標、文本內容、寬度 2、ui.iconLabel&#xff1a;在UI文件中的自定義命名 3、引入頭文件&#xff1a;#include<qpixmap.h> 函數定義&#xff1a; #pragma once#include <QWidget> #include "ui_TitleBar.h"cl…

DeepSeek全生態接入指南:官方通道+三大云平臺

DeepSeek全生態接入指南&#xff1a;官方通道三大云平臺 一、官方資源入口 1.1 核心交互平臺 &#x1f5a5;? DeepSeek官網&#xff1a; https://chat.deepseek.com/ &#xff08;體驗最新對話模型能力&#xff09; 二、客戶端工具 OllamaChatboxCherry StudioAnythingLLM …

web安全:跨站請求偽造 (CSRF)

跨站請求偽造 (CSRF) ? 跨站請求偽造&#xff08;CSRF&#xff0c;Cross-Site Request Forgery&#xff09; 是一種網絡攻擊方式&#xff0c;攻擊者誘使受害者在未經其授權的情況下執行特定操作。CSRF 利用受害者已登錄的身份和瀏覽器自動發送的認證信息&#xff08;如 Cooki…

前端ES面試題及參考答案

目錄 let/const 與 var 的區別?TDZ 是什么? 箭頭函數與普通函數的區別?箭頭函數能否作為構造函數? 模板字符串的嵌套表達式和標簽模板用法? 解構賦值的應用場景及對象 / 數組解構差異? 函數參數默認值的生效條件及暫時性死區問題? 展開運算符(...)在數組 / 對象中…