Redisson 分布式鎖的最佳實踐

Redisson 分布式鎖的最佳實踐

    • 第一、添加依賴
    • 第二、添加redisson配置類
    • 第三、添加測試類
    • 測試結果
    • 擴展知識
      • redisson鎖中lock方法和tryLock方法有什么區別
      • 鎖續約
    • 注意事項

引言

在現代分布式系統中,處理并發問題是至關重要的。分布式鎖是解決這類問題的關鍵工具之一。本文將介紹如何使用 Redisson,一個強大的 Redis 客戶端庫,來實現高性能、高可用性的分布式鎖。

基本概念

分布式鎖是多個進程或線程之間協調操作的一種機制。它通常包括三個基本操作:加鎖、持有鎖、釋放鎖。Redisson 提供了簡單而強大的接口來管理這些操作。

Redisson 分布式鎖的使用方法

第一、添加依賴

<!-- redisson分布式鎖 -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.15.5</version>
</dependency>

第二、添加redisson配置類

package com.kingmouse.lock;import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Created with IntelliJ IDEA** @author kingMouse* @date 2023/11/7 09:50* Description: redisson配置類 單機和集群自選*/@Configuration
public class RedissonConfig {/*** 單機模式* @return RedissonClient*/@Bean(destroyMethod = "shutdown")public RedissonClient redissonSingle() {// 1.創建配置Config config = new Config();// 單機模式config.useSingleServer()// 設置地址.setAddress("redis://127.0.0.1:6379")// 設置連接數.setConnectionPoolSize(10);return Redisson.create(config);}/*** 單機模式* @return RedissonClient*///    @Bean(destroyMethod = "shutdown")
//    public RedissonClient redissonCluster() {
//        // 1.創建配置
//        Config config = new Config();
//        // 集群模式-帶密碼
//        config.useClusterServers()
//                .addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001")
//                .setPassword("12356")
//                // 設置master節點最小連接數
//                .setMasterConnectionMinimumIdleSize(10)
//                // 設置slave節點最小連接數
//                .setSlaveConnectionMinimumIdleSize(10);
//        return Redisson.create(config);
//    }

第三、添加測試類

package com.kingmouse.lock;import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.TimeUnit;/*** Created with IntelliJ IDEA** @author kingMouse* @date 2023/11/5 09:54* Description:*/@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedissonLockTest {@Autowiredprivate RedissonClient redissonClient;/*** 阻塞式*/@Testpublic void testRedissonBlock() {// 設置鎖的名字,同一個名字為同一把鎖,不同名字之間互不干擾String lockKey = "kingmouse-001";// 獲取鎖對象RLock lock = redissonClient.getLock(lockKey);// 加鎖,嘗試獲取鎖,5秒后獲取不到則直接放棄lock.lock(5, TimeUnit.SECONDS);//  實際業務處理try {System.out.println("阻塞式--加鎖成功,線程 ID:" + Thread.currentThread().getId());} catch (Exception e) {log.error("業務處理異常:{}", e.getMessage());} finally {// 解鎖lock.unlock();System.out.println("阻塞式--解鎖成功,線程 ID:" + Thread.currentThread().getId());}}@Testpublic void testRedissonNonBlock() throws Exception {// 設置鎖的名字,同一個名字為同一把鎖,不同名字之間互不干擾String lockKey = "kingmouse-002";// 獲取鎖對象RLock lock = redissonClient.getLock(lockKey);// 嘗試獲取鎖,最長等待5秒,持有鎖最長30秒boolean isLock = lock.tryLock(5, 30, TimeUnit.SECONDS);if (isLock) {//  實際業務處理try {System.out.println("非阻塞式--獲取鎖成功,線程 ID:" + Thread.currentThread().getId());} catch (Exception e) {log.error("業務處理異常:{}", e.getMessage());} finally {// 解鎖lock.unlock();System.out.println("非阻塞式--解鎖成功,線程 ID:" + Thread.currentThread().getId());}}}}

測試結果

阻塞式--加鎖成功,線程 ID:1
阻塞式--解鎖成功,線程 ID:1
非阻塞式--獲取鎖成功,線程 ID:1
非阻塞式--解鎖成功,線程 ID:1

擴展知識

redisson鎖中lock方法和tryLock方法有什么區別

在 Redisson 中,lock 方法和 tryLock 方法都是用來獲取分布式鎖的,但它們在獲取鎖的方式和行為上有一些區別:

在 Redisson 中,lock 方法和 tryLock 方法都是用來獲取分布式鎖的,但它們在獲取鎖的方式和行為上有一些區別:

  1. lock 方法:

    • lock 方法是阻塞的,即如果獲取鎖失敗,調用該方法的線程會被阻塞,直到獲取到鎖為止。
    • 如果在獲取鎖時發生網絡分區或其他異常,會一直重試獲取鎖,直到獲取成功或者達到設置的超時時間為止。
    • 使用 lock 方法時,如果獲取鎖成功后,需要手動調用 unlock 方法來釋放鎖。

    例如:

    RLock lock = redisson.getLock("myLock");lock.lock();try {// 執行業務邏輯} finally {lock.unlock();}
  1. tryLock 方法:

    • tryLock 方法是非阻塞的,即如果獲取鎖失敗,方法會立即返回,不會阻塞當前線程。
    • tryLock 方法可以設置超時時間,在指定的超時時間內嘗試獲取鎖,如果超時仍未獲取到鎖,則返回 false
    • 使用 tryLock 方法時,獲取鎖成功后不需要手動釋放鎖,因為鎖會在超時時間后自動釋放。(建議使用完自動釋放鎖)

    例如:

    RLock lock = redisson.getLock("myLock");boolean isLocked = lock.tryLock(10, TimeUnit.SECONDS);if (isLocked) {try {// 執行業務邏輯} finally {lock.unlock();}} else {// 獲取鎖失敗的處理邏輯}

總結來說,lock 方法是阻塞的,會一直嘗試獲取鎖直到成功,而 tryLock 方法是非阻塞的,在指定的超時時間內嘗試獲取鎖,如果超時則返回失敗。選擇使用哪種方法取決于你的業務需求,以及是否能夠容忍等待獲取鎖的阻塞時間。

鎖續約

使用看門狗(Watchdog)可以實現鎖的自動續約:

String permitId = lock.acquire(10, TimeUnit.SECONDS);
RScheduledExecutorService executorService = redisson.getExecutorService("myExecutorService");
executorService.schedulePermitExpiration(permitId, 5, TimeUnit.SECONDS);

在這個例子中,我們使用 schedulePermitExpiration 方法每隔5秒續約一次鎖的持有時間。

注意事項

在使用分布式鎖時,需要注意以下幾點:

  1. 合理設置鎖的持有時間:不要將鎖的持有時間設置得過長,以免影響系統的并發性能。根據實際業務需求,選擇一個合適的持有時間。

  2. 使用看門狗進行續約:在需要鎖的持有時間較長的情況下,使用看門狗可以確保鎖不會在持有時間內過期,避免了手動續約的繁瑣操作。

  3. 異常處理:在加鎖、續約、釋放鎖的過程中,需要考慮可能出現的異常情況,并進行適當的處理,以確保鎖能夠被正確釋放,避免死鎖等問題。

實際應用場景

在電商系統中,分布式鎖可以用來避免商品超賣問題。在任務調度系統中,可以確保同一個任務在同一時刻只被一個節點執行,避免任務重復執行等問題。

總結

Redisson 提供了簡單而強大的分布式鎖解決方案,通過合理設置鎖的持有時間和使用看門狗進行續約,可以確保系統在高并發環境下的穩定性和可靠性。在實際應用中,開發人員可以根據業務需求選擇合適的鎖策略,并進行必要的異常處理,以實現分布式系統的高效運行。

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

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

相關文章

雙11再創新高!家電行業如何通過矩陣管理,賦能品牌增長?

雙11大促已落下帷幕&#xff0c;雖然今年不再戰報滿天飛&#xff0c;但從公布的數據來看&#xff0c;家電行業整體表現不俗。 根據抖音電商品牌業務發布的收官戰報&#xff0c;家電行業創造了成交新紀錄&#xff0c;整體同比增長125%。快手官方數據顯示&#xff0c;消電家居行業…

深入理解JMM以及并發三大特性(1)

文章目錄 1. 并發與并行2. JMM3. 并發三大特性4.總結 1. 并發與并行 并行&#xff1a;指在同一時刻&#xff0c;有多條指令在多個處理器上同時執行。所以無論從微觀還是宏觀來看&#xff0c;二者都是一起執行的。 并發&#xff1a;指在同一時刻只能有一個指令執行&#xff0c;…

基于springboot實現校園在線拍賣系統項目【項目源碼】

基于springboot實現校園在線拍賣系統演示 Javar技術 JavaScript是一種網絡腳本語言&#xff0c;廣泛運用于web應用開發&#xff0c;可以用來添加網頁的格式動態效果&#xff0c;該語言不用進行預編譯就直接運行&#xff0c;可以直接嵌入HTML語言中&#xff0c;寫成js語言&…

java開發中各個環境的適用場景

java開發中各個環境的適用場景 一.開發環境 在系統開發的經典模型&#xff0c;一般會分成 2 類 5 種環境&#xff1a; 【線下】本地環境(local)、開發環境(dev)、測試環境(test) 【線上】預發布環境(stage)、生產環境(prod) 每個環境、每個項目使用獨立的二級域名 線下、線…

Modbus轉Profinet改變局面,PLC與電力儀表秒級響應

Modbus轉Profinet改變了傳統的局面&#xff0c;實現了PLC與電力儀表之間的秒級響應。在過去&#xff0c;由于Modbus通信協議的限制&#xff0c;PLC與電力儀表之間的數據傳輸速度受到了很大的限制&#xff0c;無法滿足工業自動化領域對實時性的要求。然而&#xff0c;隨著Modbus…

【云原生 Prometheus篇】Prometheus架構詳解與核心組件的應用實例(Exporters、Grafana...)

Prometheus Part1 一、常用的監控系統1.1 簡介1.2 Prometheus和zabbix的區別 二、Prometheus2.1 簡介2.2 Prometheus的主要組件1&#xff09;Prometheus server2&#xff09;Exporters3&#xff09;Alertmanager4&#xff09;Pushgateway5&#xff09;Grafana 2.3 Prometheus的…

openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數

文章目錄 openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數130.1 背景信息130.2 GUC參數設置130.3 操作步驟130.4 示例 openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數 130.1 背景信息 openGauss提供了多種修改GUC參數的方法&#xff0c;用戶可…

【網絡】數據鏈路層協議

數據鏈路層協議 一、鏈路層解決的問題二、以太網協議1、局域網技術2、令牌環網&#xff08;了解&#xff09;3、以太網通信原理4、 MAC地址5、以太網幀格式6、碰撞避免7、最大傳輸單元MTU 二、ARP協議1、ARP數據的格式2、ARP協議的工作流程3、ARP緩存表4、ARP協議中的一些問題7…

11月23日星期四今日早報簡報微語報早讀

11月23日星期四&#xff0c;農歷十月十一&#xff0c;早報微語早讀。 1、我國5G基站總數達321.5萬個&#xff1b; 2、2023年兩院院士增選結果揭曉&#xff0c;共133人當選&#xff1b; 3、北京低保標準提升至每人每月1395元&#xff1b; 4、上海制定體育發展條例&#xff1a…

多重背包問題的優化 學習筆記 AcWing 5. 多重背包問題 II(算法基礎課)

乘法原理 百度百科 乘法原理是說把多個步驟的所有方法相乘&#xff0c;表示整個事件所有可能的解決方法 原題 有 N&#xfffd; 種物品和一個容量是 V&#xfffd; 的背包。 第 i&#xfffd; 種物品最多有 si&#xfffd;&#xfffd; 件&#xff0c;每件體積是 vi&#…

程序員必讀!深入解析Java線程調度算法神秘面紗!

哈嘍大家好&#xff0c;我是小米&#xff01;今天我們要聊的話題是關于Java中的線程調度算法。這可是一個技術大拿們在面試時常常拿出來考察我們的點子呢&#xff01;廢話不多說&#xff0c;讓我們一起深入了解一下吧&#xff01; 線程調度算法的背后 首先&#xff0c;讓我們…

[Linux] shell腳本之循環

一、循環定義 一組被重復執行的語句稱之為 循環體,能否繼續重復,決定循環的終止條件。 循環語句 是由循環體及循環的終止條件兩部分組成的。 二、for循環 2.1 帶列表循環 語法 for 變量名 in 取值列表do 命令序列 done 花括號用法&#xff1a; 花括號{ }和seq在for循環…

設計模式——狀態模式介紹

狀態模式是一種行為設計模式&#xff0c;它允許對象在內部狀態改變時改變它的行為。它基于對象的內部狀態而改變其行為&#xff0c;看起來好像修改了對象的類。 狀態模式的關鍵組件有三個&#xff1a;上下文(Context)、狀態(State)和具體狀態(Concrete State)。 下面是一個例…

年輕有為!2023兩院院士增選揭榜 45歲顏寧當選

大家好&#xff0c;我是極智視界&#xff0c;歡迎關注我的公眾號&#xff0c;獲取我的更多前沿科技分享 邀您加入我的知識星球「極智視界」&#xff0c;星球內有超多好玩的項目實戰源碼和資源下載&#xff0c;鏈接&#xff1a;https://t.zsxq.com/0aiNxERDq 通常&#xff0c;兩…

電商網站選擇云服務器要考慮什么?

極高的安全性 交易平臺最重要的是數據安全&#xff0c;這涉及到產品、用戶、平臺信息等&#xff0c;能夠保護數據隱私的安全&#xff0c;是網站交易的首要原則。 2020年&#xff0c;數據泄露、網絡滲透、大量數據被銷售、勒索軟件爆發......每個網站都可能成為黑客的目標&#…

CuratorFrameworkFactory.builder()方法可配置屬性

CuratorFrameworkFactory.builder()方法可以配置以下屬性&#xff1a; 1. connectString&#xff1a;ZooKeeper服務器的連接字符串。 2. sessionTimeoutMs&#xff1a;ZooKeeper會話超時時間。 3. connectionTimeoutMs&#xff1a;ZooKeeper連接超時時間。 4. retryPolicy&…

springboot自動重啟及SpringBoot Developer tools簡介

項目中引用了SpringBoot Developer tools&#xff0c;修改類后會自動重啟。 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional&…

BTS-GAN:基于MRI和條件對抗性網絡的乳腺腫瘤計算機輔助分割系統

BTS-GAN: Computer-aided segmentation system for breast tumor using MRI and conditional adversarial networks BTS-GAN&#xff1a;基于MRI和條件對抗性網絡的乳腺腫瘤計算機輔助分割系統背景貢獻實驗方法Parallel dilated convolution module&#xff08;并行擴展卷積模塊…

逸學java【初級菜鳥篇】9.5枚舉

hi&#xff0c;我是逸塵&#xff0c;一起學java吧 枚舉是信息的標志和分類 當一個變量有幾種固定可能的取值時&#xff0c;就可以將它定義為類型的枚舉。 優點&#xff1a;代碼可讀性好&#xff0c;入參約束嚴謹&#xff0c;代碼優雅&#xff0c;是最好的信息分類技術&#x…

【AI讀論文】AutoML的8年回顧:分類、綜述與趨勢

論文標題&#xff1a;Eight years of AutoML: categorisation, review and trends 論文鏈接&#xff1a;https://link.springer.com/article/10.1007/s10115-023-01935-1 本文主要圍繞自動機器學習&#xff08;AutoML&#xff09;展開了系統性的文獻綜述&#xff0c;總結了該領…