golang 實現基于redis的并行流量控制(計數鎖)

在業務開發中,有時需要對某個操作在整個集群中限制并發度,例如限制大模型對話的并行數。基于redis zset實現計數鎖,做個筆記。

關鍵詞:并行流量控制、計數鎖

package redisutilimport ("context""fmt""math""time""github.com/go-redis/redis/v9"
)// AcquireZSetLock 借助redis zset數據結構實現分布式計數鎖。可用于計數任務運行數,防止超限。返回值:zset大小、釋放鎖的函數、錯誤信息
func AcquireZSetLock(ctx context.Context, c redis.Client, key string, element string, zsetMaxSize int,expiresIn time.Duration, syncWait time.Duration) (int, func() error, error) {ctx, cancel := context.WithTimeout(ctx, syncWait)defer cancel()for i := 0; ; i++ {select {case <-ctx.Done(): // 接到取消信號,按插入失敗處理return -1, func() error { return nil }, ctx.Err()default:}size, err := insertElementToZsetLock(ctx, c, key, element, zsetMaxSize, expiresIn)if err != nil {second := 0.4 + 0.6*math.Exp(-0.17*float64(i)) // f(i=0) = 1.0; f(i=10) = 0.5096,即第10次就會衰減到0.5096秒second = max(second, 0.5)                      // 最小間隔0.5秒,防止過于頻繁的請求time.Sleep(time.Duration(second*1000) * time.Millisecond)}releaseFunc := func() error {result, err := c.ZRem(context.Background(), key, element).Result()if err != nil {return fmt.Errorf("redis zrem error: %v. return=%d", err, result)}return nil}return size, releaseFunc, nil}
}// insertElementToZsetLock 插入元素到zset,并刪除已過期的元素
func insertElementToZsetLock(ctx context.Context, c redis.Client, key string, element string, zsetMaxSize int, expiresIn time.Duration) (int, error) {luaScript := `local zsetName = KEYS[1]local memberName = ARGV[1]local currentTime = tonumber(ARGV[2])local deadTime = tonumber(ARGV[3])local sizeLimit = tonumber(ARGV[4])-- 刪除已過期的元素redis.call("ZREMRANGEBYSCORE", zsetName, "-inf", currentTime)-- 獲取集合的大小local setSize = redis.call('ZCard', zsetName)-- 如果集合大小小于限制值,則添加元素,并返回集合大小if setSize < sizeLimit thenredis.call('ZAdd', zsetName, deadTime, memberName)local expireTime = deadTime - currentTimeif expireTime > 0 thenredis.call('EXPIRE', zsetName, expireTime)endreturn setSize+1endreturn -1`currentTime := time.Now().Unix()deadTime := time.Now().Add(expiresIn).Unix() // 過期時間 Unix秒ret, err := c.Do(ctx, "EVAL", luaScript, 1, key, element, currentTime, deadTime, zsetMaxSize).Result()if err != nil {return -1, err}if ret.(int64) < 0 {return zsetMaxSize, fmt.Errorf("zset size reach max size: %d", zsetMaxSize)}return int(ret.(int64)), nil
}

使用示例:

size, release, err := AcquireZSetLock(ctx, client, key, element, 10, 10*time.Second, 3*time.Second)
defer release()
if err != nil {fmt.Println(err)
}

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

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

相關文章

從線性方程組角度理解公式 s=n?r(3E?A)

從線性方程組角度理解公式 sn?r(3E?A) 這個公式本質上是 ?齊次線性方程組解空間維度 的直接體現。下面通過三個關鍵步驟解釋其在線性方程組中的含義&#xff1a; 1. ?公式對應的線性方程組 考慮矩陣方程&#xff1a; (3E?A)x0 其中&#xff1a; x 是 n 維未知向量3E?…

Docker 在 AI 開發中的實踐:GPU 支持與深度學習環境的容器化

人工智能(AI)和機器學習(ML),特別是深度學習,正以前所未有的速度發展。然而,AI 模型的開發和部署并非易事。開發者常常面臨復雜的依賴管理(如 Python 版本、TensorFlow/PyTorch 版本、CUDA、cuDNN)、異構硬件(CPU 和 GPU)支持以及環境復現困難等痛點。這些挑戰嚴重阻…

解決CSDN等網站訪問不了的問題

原文網址&#xff1a;解決CSDN等網站訪問不了的問題-CSDN博客 簡介 本文介紹解決CSDN等網站訪問不了的方法。 問題描述 CSDN訪問不了了&#xff0c;頁面是空的。 問題解決 方案1&#xff1a;修改DNS 可能是dns的問題&#xff0c;需要重新配置。 國內常用的dns是&#x…

使用tortoisegit連接遠程倉庫進行克隆、拉取、獲取、提交、推送、新建/切換分支、重命名、刪除的一套流程(附帶巨全面的git命令)

1.整備好tortoisegit工具。 2.新建一個文件夾&#xff0c;并進入這個文件夾后鼠標右擊&#xff08;選擇克隆&#xff09;&#xff1a; 3.先去項目中拿到https地址&#xff0c;再填入&#xff1a; 4.新建分支&#xff0c;右擊克隆到本地的項目文件&#xff1a; 5.推送到遠程&am…

ArcGIS Pro 3.4 二次開發 - 地圖創作 1

環境:ArcGIS Pro SDK 3.4 + .NET 8 文章目錄 ArcGIS Pro 3.4 二次開發 - 地圖創作 11 樣式管理1.1 如何通過名稱獲取項目中的樣式1.2 如何創建新樣式1.3 如何向項目添加樣式1.4 如何從項目中移除樣式1.5 如何向樣式添加樣式項1.6 如何從樣式中移除樣式項1.7 如何判斷樣式是否可…

Express 集成Sequelize+Sqlite3 默認開啟WAL 進程間通信 Conf 打包成可執行 exe 文件

代碼&#xff1a;express-exe: 將Express開發的js打包成exe服務丟給客戶端使用 實現目標 Express 集成 Sequelize 操作 Sqlite3 數據庫&#xff1b; 啟動 Sqlite3 時默認開啟 WAL 模式&#xff0c;避免讀寫互鎖&#xff0c;支持并發讀&#xff1b; 利用 Conf 實現主進程與 Ex…

.Net Framework 4/C# 初識 C#

一、C# 專欄 由于博主原先是做的Linux C/C 嵌入式領域&#xff0c;因此對 C# 也較為懵懂&#xff0c;C# 是典型的 OOP 編程&#xff0c;這一點與 C 類似&#xff0c;但是在語法上&#xff0c;C# 移除了對指針的運用以及內存管理&#xff0c;所以既不用考慮指針的復雜運用也不用…

Python趣學篇:Pygame實現粒子煙花綻放效果

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 專欄介紹:《Python星球日記》?? 目錄 一、項目亮點與效果預覽1. 核心特色功能2. 技術學習價值二、技術原理深度解析1. 向量運算:煙花運動的數學基…

NiceGUI 是一個基于 Python 的現代 Web 應用框架

NiceGUI 是一個基于 Python 的現代 Web 應用框架&#xff0c;它允許開發者直接使用 Python 構建交互式 Web 界面&#xff0c;而無需編寫前端代碼。以下是 NiceGUI 的主要功能和特點&#xff1a; 核心功能 1.簡單易用的 UI 組件 提供按鈕、文本框、下拉菜單、滑塊、圖表等常見…

Linux中的mysql邏輯備份與恢復

一、安裝mysql社區服務 二、數據庫的介紹 三、備份類型和備份工具 一、安裝mysql社區服務 這是小編自己寫的&#xff0c;沒有安裝的去看看 Linux換源以及yum安裝nginx和mysql-CSDN博客 二、數據庫的介紹 2.1 數據庫的組成 數據庫是一堆物理文件的集合&#xff0c;主要包括…

鴻蒙UI開發——組件的自適應拉伸

1、概 述 針對常見的開發場景&#xff0c;ArkUI開發框架提供了非常多的自適應布局能力&#xff0c;這些布局可以獨立使用&#xff0c;也可多種布局疊加使用。本文針對ArkUI提供的拉伸能力做簡單討論。 拉伸能力是指容器組件尺寸發生變化時&#xff0c;增加或減小的空間全部分…

K 值選對,準確率翻倍:KNN 算法調參的黃金法則

目錄 一、背景介紹 二、KNN 算法原理 2.1 核心思想 2.2 距離度量方法 2.3 算法流程 2.4算法結構&#xff1a; 三、KNN 算法代碼實現 3.1 基于 Scikit-learn 的簡單實現 3.2 手動實現 KNN&#xff08;自定義代碼&#xff09; 四、K 值選擇與可視化分析 4.1 K 值對分類…

Azure DevOps Server 2022.2 補丁(Patch 5)

微軟Azure DevOps Server的產品組在4月8日發布了2022.2 的第5個補丁。下載路徑為&#xff1a;https://aka.ms/devops2022.2patch5 這個補丁的主要功能是修改了代理(Agent)二進制安裝文件的下載路徑&#xff1b;之前&#xff0c;微軟使用這個CND(域名為vstsagentpackage.azuree…

PHP7+MySQL5.6 查立得輕量級公交查詢系統

# PHP7MySQL5.6 查立得輕量級公交查詢系統 ## 系統簡介 本系統是一個基于PHP7和MySQL5.6的輕量級公交查詢系統(40KB級)&#xff0c;支持線路查詢、站點查詢和換乘查詢功能。系統采用原生PHPMySQL開發&#xff0c;無需第三方框架&#xff0c;適合手機端訪問。 首發版本&#x…

Vue-Cropper:全面掌握圖片裁剪組件

Vue-Cropper 完全學習指南&#xff1a;Vue圖片裁剪組件 &#x1f3af; 什么是 Vue-Cropper&#xff1f; Vue-Cropper 是一個簡單易用的Vue圖片裁剪組件&#xff0c;支持Vue2和Vue3。它提供了豐富的配置選項和回調方法&#xff0c;可以滿足各種圖片裁剪需求。 &#x1f31f; …

[Go] Option選項設計模式 — — 編程方式基礎入門

[Go] Option選項設計模式 — — 編程方式基礎入門 全部代碼地址&#xff0c;歡迎?? Github&#xff1a;https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-option 1 介紹 在 Go 開發中&#xff0c;我們經常遇到需要處理多參數配置的場景。傳統方…

【Unity開發】控制手機移動端的震動

&#x1f43e; 個人主頁 &#x1f43e; 阿松愛睡覺&#xff0c;橫豎醒不來 &#x1f3c5;你可以不屠龍&#xff0c;但不能不磨劍&#x1f5e1; 目錄 一、前言二、Unity的Handheld.Vibrate()三、調用Android原生代碼四、NiceVibrations插件五、DeviceVibration插件六、控制游戲手…

Linux 軟件安裝方式全解(適用于 CentOS/RHEL 系統)

&#x1f427; Linux 軟件安裝方式全解&#xff08;適用于 CentOS/RHEL 系統&#xff09; 在 Linux 系統中&#xff0c;軟件安裝方式豐富多樣&#xff0c;常見于以下幾種方式&#xff1a; 安裝方式命令/工具說明軟件包管理器&#xff08;推薦&#xff09;yum, dnf, apt, zypp…

前端面試題-HTML篇

1. 請談談你對 Web 標準以及 W3C 的理解和認識。 我對 Web 標準 的理解是,它就像是互聯網世界的“交通規則”,由 W3C(World Wide Web Consortium,萬維網聯盟) 這樣一個國際性組織制定。這些規則規范了我們在編寫 HTML、CSS 和 JavaScript 時應該遵循的語法和行為,比如要…

ERROR: column cl.udt_name does not exist LINE 1 navicat打開金倉表報錯

描述&#xff1a; ERROR: column cl.udt_name does not exist LINE 1: …a.columns cl LEFT JOlN pg type ty ON ty.typname cl.udt nam. navicat連上金倉數據庫之后&#xff0c;想打開一張表看看&#xff0c;每張表都報這個錯&#xff0c;打不開 解決方案&#xff1a; 網上…