原生redis實現分布式鎖

原生 Redis(Jedis、Lettuce) 實現分布式鎖,可以參考 Redisson 的原理,但需要自己處理鎖的自動續期、故障恢復等細節。核心思路是使用 Redis 的 SET NX EXSET PX NX 命令來實現互斥鎖,并利用 Lua 腳本 保障原子性。

實現思路

  • 獲取鎖
    • SET key value NX PX expiration,確保鎖只能被一個線程獲取,并設置過期時間。
  • 自動續期
    • 通過 后臺線程 定時續期,防止業務執行時間過長導致鎖超時釋放。
  • 釋放鎖
    • 通過 Lua 腳本 保證原子性,只有 當前線程 持有鎖時才能釋放。

完整代碼

1. 依賴引入

使用 Jedis 作為 Redis 客戶端:

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version>
</dependency>

2. 分布式鎖實現

獲取鎖
import redis.clients.jedis.Jedis;
import java.util.UUID;public class RedisLock {private static final String LOCK_SUCCESS = "OK";private static final String LOCK_KEY = "my_lock";private static final int EXPIRE_TIME = 10_000; // 10秒過期private final Jedis jedis;private final String lockValue; // 唯一標識鎖的持有者public RedisLock(Jedis jedis) {this.jedis = jedis;this.lockValue = UUID.randomUUID().toString(); // 防止誤刪}public boolean tryLock() {String result = jedis.set(LOCK_KEY, lockValue, "NX", "PX", EXPIRE_TIME);return LOCK_SUCCESS.equals(result); // 返回 true 代表加鎖成功}
}
自動續期

如果業務執行時間超過 10s,鎖會自動釋放,所以需要定時續期

import java.util.concurrent.*;public class LockRenewal {private static final int RENEWAL_INTERVAL = 5000; // 每5秒續期private final Jedis jedis;private final String lockValue;private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);public LockRenewal(Jedis jedis, String lockValue) {this.jedis = jedis;this.lockValue = lockValue;}public void startRenewal() {scheduler.scheduleAtFixedRate(() -> {if (lockValue.equals(jedis.get("my_lock"))) {jedis.pexpire("my_lock", 10_000);}}, 0, RENEWAL_INTERVAL, TimeUnit.MILLISECONDS);}public void stopRenewal() {scheduler.shutdown();}
}
釋放鎖

使用 Lua 腳本,確保只有 持有鎖的線程 才能刪除:

public void unlock() {String luaScript ="if redis.call('get', KEYS[1]) == ARGV[1] then " +"   return redis.call('del', KEYS[1]) " +"else " +"   return 0 " +"end";jedis.eval(luaScript, 1, "my_lock", lockValue);
}

3. 使用示例

Jedis jedis = new Jedis("localhost", 6379);
RedisLock redisLock = new RedisLock(jedis);
LockRenewal renewal = new LockRenewal(jedis, redisLock.lockValue);if (redisLock.tryLock()) {renewal.startRenewal(); // 開啟自動續期try {// 執行業務邏輯System.out.println("獲取到鎖,執行業務...");Thread.sleep(15000); // 模擬業務執行時間超過鎖的原始超時時間} catch (InterruptedException e) {e.printStackTrace();} finally {redisLock.unlock();renewal.stopRenewal(); // 停止續期}
} else {System.out.println("獲取鎖失敗");
}

總結

  1. 互斥性SET NX PX 確保只有一個線程能獲取鎖。
  2. 自動續期:定期 PEXPIRE 延長鎖的存活時間。
  3. 安全釋放:Lua 腳本保證只有鎖的持有者才能刪除。

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

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

相關文章

論文筆記:Rethinking Graph Neural Networks for Anomaly Detection

目錄 摘要 “右移”現象 beta分布及其小波 實驗 《Rethinking Graph Neural Networks for Anomaly Detection》&#xff0c;這是一篇關于圖&#xff08;graph&#xff09;上異常節點診斷的論文。 論文出處&#xff1a;ICML 2022 論文地址&#xff1a;Rethinking Graph Ne…

神經網絡常見激活函數 6-RReLU函數

文章目錄 RReLU函數導函數函數和導函數圖像優缺點pytorch中的RReLU函數tensorflow 中的RReLU函數 RReLU 隨機修正線性單元&#xff1a;Randomized Leaky ReLU 函數導函數 RReLU函數 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…

Vue(6)

一.路由板塊封裝 &#xff08;1&#xff09;路由的封裝抽離 目標&#xff1a;將路由板塊抽離出來 好處&#xff1a;拆分板塊&#xff0c;利于維護 // 路由的使用步驟 5 2 // 5個基礎步驟 // 1. 下載 v3.6.5 // 2. 引入 // 3. 安裝注冊 Vue.use(Vue插件) // 4. 創建路由對象…

【python】matplotlib(animation)

文章目錄 1、matplotlib.animation1.1、FuncAnimation1.2、修改 matplotlib 背景 2、matplotlib imageio2.1、折線圖2.2、條形圖2.3、散點圖 3、參考 1、matplotlib.animation 1.1、FuncAnimation matplotlib.animation.FuncAnimation 是 Matplotlib 庫中用于創建動畫的一個…

【東莞常平】戴爾R710服務器不開機維修分享

1&#xff1a;2025-02-06一位老客戶的朋友剛開工公司ERP服務器一臺戴爾老服務器故障無法開機&#xff0c;于是經老客戶介紹找到我們。 2&#xff1a;服務器型號是DELL PowerEdge R710 這個服務器至少也有15年以上的使用年限了。 3&#xff1a;客戶反饋的故障問題為&#xff1a;…

Spring AI -使用Spring快速開發ChatGPT應用

前言 Spring在Java生態中一直占據大半江山。最近我發現Spring社區推出了一個Spring AI項目&#xff0c;目前該項目還屬于Spring實驗性項目&#xff0c;但是我們可以通過該項目&#xff0c;可以非常快速的開發出GPT對話應用。 本篇文章將會對SpringAI進行簡單的介紹和使用&#…

經典排序算法復習----C語言

經典排序算法復習 分類 交換類 冒泡快排 分配類 計數排序基數排序 選擇類 選擇排序 堆排序 歸并類 歸并排序 插入類 直接插入排序 希爾排序 折半插入排序 冒泡排序 基于交換。每一輪找最大值放到數組尾部 //冒泡排序 void bubSort(int* arr,int size){bool sorte…

BFS解決拓撲排序(3題)

目錄 拓撲排序 1.如何排序&#xff1f; 2.如何形成拓撲排序 3.如何建圖 1.看數據稠密度 2. 根據算法流程靈活建圖 1.課程表 2.課程表2 3.火星詞典 拓撲排序 找到做事情的先后順序&#xff0c;拓撲排序的結果可能不是唯一的 1.如何排序&#xff1f; 1.找出圖中入度為…

kafka 3.5.0 raft協議安裝

前言 最近做項目&#xff0c;需要使用kafka進行通信&#xff0c;且只能使用kafka&#xff0c;筆者沒有測試集群&#xff0c;就自己搭建了kafka集群&#xff0c;實際上筆者在很早之前就搭建了&#xff0c;因為當時還是zookeeper&#xff08;簡稱ZK&#xff09;注冊元數據&#…

Unity項目接入xLua的一種流程

1. 導入xlua 首先導入xlua&#xff0c;這個不用多說 2. 編寫C#和Lua交互腳本 基礎版本&#xff0c;即xlua自帶的版本 using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System; using System.IO;[Serializable] public…

四次揮手詳解

文章目錄 一、四次揮手各狀態FIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSE 二、雙方同時調用close()&#xff0c;FIN_WAIT_1狀態后進入CLOSING狀態CLOSING狀態 三、TIME_WAIT狀態詳解(1) TIME_WAIT狀態下的2MSL是什么MSL &#xff08;報文最大生存時間&#xff09;為…

【嵌入式 Linux 音視頻+ AI 實戰項目】瑞芯微 Rockchip 系列 RK3588-基于深度學習的人臉門禁+ IPC 智能安防監控系統

前言 本文主要介紹我最近開發的一個個人實戰項目&#xff0c;“基于深度學習的人臉門禁 IPC 智能安防監控系統”&#xff0c;全程滿幀流暢運行。這個項目我目前全網搜了一圈&#xff0c;還沒發現有相關類型的開源項目。這個項目只要稍微改進下&#xff0c;就可以變成市面上目前…

java: framework from BLL、DAL、IDAL、MODEL、Factory using oracle

oracel 21c sql: -- 創建 School 表 CREATE TABLE School (SchoolId CHAR(5) NOT NULL,SchoolName NVARCHAR2(500) NOT NULL,SchoolTelNo VARCHAR2(8) NULL,PRIMARY KEY (SchoolId) );CREATE OR REPLACE PROCEDURE addschool(p_school_id IN CHAR,p_school_name IN NVARCHAR2,p…

解決錯誤:CondaHTTPError: HTTP 000 CONNECTION FAILED for url

解決錯誤&#xff1a;CondaHTTPError: HTTP 000 CONNECTION FAILED for url 查看channels:vim ~/.condarcshow_channel_urls: true channels:- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/…

Apache APISIX 快速入門

文章目錄 apisix 快速入門什么是apisix有了 NGINX 和 Kong&#xff0c;為什么還需要 Apache APISIX&#xff1f;軟件架構基于 Nginx 開源版本&#xff0c;而 Nginx 并不支持動態配置&#xff0c;為什么 Apache APISIX 聲稱自己可以實現動態配置&#xff1f; 安裝配置 APISIX配置…

2025嵌入式高頻面試題解析

一、概述 到了年初&#xff0c;是求職者最活躍的時間。本文梳理了嵌入式高頻面試題&#xff0c;幫助求職者更好地準備面試&#xff0c;同時也為技術愛好者提供深入學習嵌入式知識的參考。 二、C 語言基礎 2.1 指針與數組 問題 1&#xff1a;指針和數組的區別是什么&#xf…

1.攻防世界 baby_web

題目描述這里有提示&#xff0c;初始頁面 進入題目頁面如下 很簡潔的頁面只有一行HELLO WORLD ctrlu查看了源碼也沒有信息 用burp suite抓包&#xff0c;并發送到重放器 根據提示&#xff08;初始頁面&#xff09;修改訪問index.php文件 index.php index.php 是一種常見的…

什么是三層交換技術?與二層有什么區別?

什么是三層交換技術&#xff1f;讓你的網絡飛起來&#xff01; 一. 什么是三層交換技術&#xff1f;二. 工作原理三. 優點四. 應用場景五. 總結 前言 點個免費的贊和關注&#xff0c;有錯誤的地方請指出&#xff0c;看個人主頁有驚喜。 作者&#xff1a;神的孩子都在歌唱 大家好…

【機器學習】數據預處理之數據歸一化

數據預處理之數據歸一化 一、摘要二、數據歸一化概念三、數據歸一化實現方法3.1 最值歸一化方法3.2 均值方差歸一化方法 一、摘要 本文主要講述了數據歸一化&#xff08;Feature Scaling&#xff09;的重要性及其方法。首先通過腫瘤大小和發現時間的例子&#xff0c;說明了不同…

【AIGC】語言模型的發展歷程:從統計方法到大規模預訓練模型的演化

博客主頁&#xff1a; [小????????] 本文專欄: AIGC | ChatGPT 文章目錄 &#x1f4af;前言&#x1f4af;語言模型的發展歷程&#xff1a;從統計方法到大規模預訓練模型的演化1 統計語言模型&#xff08;Statistical Language Model, SLM&#xff09;&#xff1a;統…