分布式微服務--ZooKeeper作為分布式鎖

看這篇博客之前可以先去了解博主的另一篇講解ZooKeeper的博客:分布式微服務--ZooKeeper的客戶端常用命令 & Java API 操作-CSDN博客

1. 為什么需要分布式鎖?

在分布式系統中,多個服務節點可能同時訪問或修改同一份共享資源(例如數據庫記錄、緩存數據、文件等)。
如果不加限制,容易出現數據不一致或競爭條件。
因此,需要一種機制來保證:同一時刻只有一個節點能訪問某資源。這就是分布式鎖的意義。

常見分布式鎖實現方式:

  • 基于 Redis

  • 基于 ZooKeeper

  • 基于 數據庫

其中 ZooKeeper 實現分布式鎖更安全可靠,因為它的核心是 強一致性 + 臨時順序節點機制


2. ZooKeeper 的分布式鎖原理

ZooKeeper 提供的 臨時節點(Ephemeral)有序節點(Sequential) 是實現分布式鎖的關鍵。

核心思想:

  1. 創建鎖節點
    所有客戶端到某個固定路徑(如 /lock)下創建一個 臨時順序節點,例如:

    /lock/lock_00000001
    /lock/lock_00000002
    /lock/lock_00000003
    
    • 臨時節點保證客戶端宕機或斷開時自動刪除。

    • 順序節點保證多個客戶端的排隊順序。

  2. 獲取鎖
    客戶端判斷自己創建的節點是否是 序號最小的節點

    • 如果是 → 獲取鎖成功。

    • 如果不是 → 監聽比自己小的前一個節點,等待其釋放。

  3. 釋放鎖
    客戶端執行完業務邏輯后,刪除自己的節點 → 喚醒下一個等待者。


3. 分布式鎖實現步驟

假設我們要對某個共享資源 order 加鎖。

1)獲取鎖

  • 客戶端在 /lock/order 下創建臨時順序節點,例如:
    /lock/order/lock_00000010

  • 獲取 /lock/order 下所有子節點,并排序。

  • 如果自己是最小的節點 → 獲得鎖。

  • 否則 → 監聽自己前一個節點。

2)釋放鎖

  • 客戶端完成業務邏輯后,刪除自己的節點。

  • ZooKeeper 會通知下一個等待者。

3)異常情況

  • 如果客戶端宕機或與 ZooKeeper 斷開連接,ZooKeeper 會自動刪除臨時節點,從而避免鎖“死鎖”。


4. ZooKeeper 分布式鎖代碼示例

基于 Curator(推薦)

Curator 是 ZooKeeper 的一個高級客戶端,封裝了分布式鎖。


樣例代碼(本次使用的鎖是InterProcessMutex):

xml

  <!--curator--><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.0</version></dependency>

代碼


/*** 模擬12306售票系統 —— 使用 Zookeeper 分布式鎖保證并發安全*/
public class Ticket12306 implements Runnable{// 模擬數據庫中的票數private int tickets = 10;// 分布式可重入鎖對象(Curator 提供)private InterProcessMutex lock ;public Ticket12306(){// 1. 定義重試策略:初始等待時間 3 秒,最多重試 10 次RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);// 2. 通過 builder 模式創建 CuratorFramework 客戶端CuratorFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181") // Zookeeper 連接地址.sessionTimeoutMs(60 * 1000) // 會話超時時間.connectionTimeoutMs(15 * 1000) // 連接超時時間.retryPolicy(retryPolicy) // 指定重試策略.build();// 3. 開啟連接client.start();// 4. 創建分布式鎖對象,指定鎖的路徑(ZK 節點)//   不同客戶端只要路徑一樣,就能實現互斥lock = new InterProcessMutex(client,"/lock");}@Overridepublic void run() {while(true){try {// 1. 嘗試獲取鎖,最多等待 3 秒lock.acquire(3, TimeUnit.SECONDS);// 2. 拿到鎖后執行業務邏輯 —— 賣票if(tickets > 0){System.out.println(Thread.currentThread()+":" + tickets);Thread.sleep(100); // 模擬業務處理耗時tickets--; // 賣出一張票}} catch (Exception e) {e.printStackTrace();} finally {// 3. 無論如何,最后都要釋放鎖,避免死鎖try {lock.release();} catch (Exception e) {e.printStackTrace();}}}}
}

測試:

/*** 測試類:模擬多個客戶端同時搶票*/
public class LockTest {public static void main(String[] args) {// 創建一個 Ticket12306 對象(共享 10 張票)Ticket12306 ticket12306 = new Ticket12306();// 創建兩個線程,模擬兩個不同的售票平臺(攜程、飛豬)Thread t1 = new Thread(ticket12306,"攜程");Thread t2 = new Thread(ticket12306,"飛豬");// 啟動線程,同時賣票t1.start();t2.start();}
}

? 總結:

  1. InterProcessMutex 是 Curator 提供的 可重入分布式鎖,底層用 Zookeeper 的臨時順序節點實現。

  2. lock.acquire() 獲取鎖,獲取不到會阻塞(或超時返回 false)。

  3. lock.release() 釋放鎖,必須寫在 finally,避免異常導致死鎖。

  4. 這種方式可以模擬 多進程/多機器的并發安全,保證同一時刻只有一個客戶端在修改票數。


5. ZooKeeper 分布式鎖的優缺點

? 優點

  • 強一致性:ZK 的數據一致性保證了鎖的可靠性。

  • 自動釋放:客戶端宕機,臨時節點會自動刪除,避免死鎖。

  • 公平性:順序節點機制,保證先來先服務。

? 缺點

  • 性能較低:每次加鎖/解鎖都需要與 ZK 通信,適合低并發場景。

  • 部署復雜:需要搭建 ZooKeeper 集群。

  • 羊群效應:節點刪除時可能觸發大量客戶端通知(不過監聽前一個節點可以緩解)。


6. 使用場景

  • 訂單系統(防止超賣)

  • 分布式定時任務(同一時間只允許一個節點執行)

  • 共享資源訪問控制(文件、緩存等)


7. 總結

  • ZooKeeper 分布式鎖依賴 臨時順序節點 + watcher 機制

  • Curator 封裝了常用的鎖(InterProcessMutex),開發更方便。

  • 適合一致性要求高、并發量不是極高的業務場景。

  • 高并發下更推薦 Redis 分布式鎖(性能更好,但需要妥善解決可靠性問題)。

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

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

相關文章

基于容器化云原生的 MySQL 及中間件高可用自動化集群項目

1 項目概述 本項目旨在構建一個高可用、高性能的 MySQL 集群,能夠處理大規模并發業務。通過容器化部署、多級緩存、完善的監控和備份策略,確保數據庫服務的連續性和數據安全性。 架構總覽 預期目標 數據庫服務可用性達到 99.99% 支持每秒 thousands 級別的并發訪問 實現秒…

如何將 iPhone 備份到電腦/PC 的前 5 種方法

定期備份你的 iPhone&#xff08;最好每兩周一次&#xff09;對于保護你的數據至關重要。它確保了如果設備損壞、丟失或被盜&#xff0c;或者你換了新手機&#xff0c;你不會丟失重要信息&#xff0c;并且可以輕松地從備份中恢復應用程序、照片、設置等。如果你不確定如何備份 …

國產AI芯片編程模型深度對比:寒武紀MLU vs 壁仞BR100異構計算設計

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;國產AI芯片的崛起與挑戰 隨著人工智能技術的飛速…

【項目】基于One Thread One Loop模型的高性能網絡庫實現 - 項目介紹與前置知識

目錄 項目介紹 HTTP服務器基本認識 Reactor模式基本認識 單Reactor單線程模式認識 單Reactor多線程模式認識 多Reactor多線程模式認識 模塊劃分 Server模塊 Buffer模塊 Socket模塊 Channel模塊 Connection模塊 Acceptor模塊 TimerQueue模塊 Poller模塊 EventLo…

lua中table鍵類型及lua中table的初始化有幾種方式

在 Lua 中&#xff0c;table 的鍵幾乎可以是任何類型&#xff0c;但有幾個重要的規則和最佳實踐需要了解。1. 主要鍵類型(1) 字符串 (string)這是最常見、最推薦的鍵類型。local person {name "Alice", -- 等同于 ["name"] "Alice"["age…

matlab實現利用雙MZI產生RZ33-QPSK信號

利用MATLAB實現雙MZI產生RZ33-QPSK信號的代碼&#xff1a; 參數設置 % 信號參數 fs 1e6; % 采樣頻率 fc 10e6; % 載波頻率 T 1e-6; % 符號周期 N 1000; % 采樣點數 t 0:1/fs:(N-1)/fs; % 時間向量生成QPSK信號 % 生成隨機二進制序列 data randi([0,1],1,N);% 將二進制序列…

Vue響應式更新 vs React狀態更新:兩種范式的底層邏輯與實踐差異

在現代前端框架中&#xff0c;Vue和React作為兩大主流選擇&#xff0c;分別采用了截然不同的狀態管理與更新機制。Vue的“響應式更新”通過自動追蹤依賴實現數據與視圖的聯動&#xff0c;而React的“狀態更新”則依賴顯式setState觸發重新渲染。本文將從底層原理、更新流程、優…

Spring MVC 的常用注解

一、控制器相關注解ControllerController注解用于標記一個類為 Spring MVC 的控制器。在 Spring MVC 框架里&#xff0c;控制器扮演著關鍵角色&#xff0c;負責接收 HTTP 請求并返回響應。當一個類被Controller注解標記后&#xff0c;Spring 容器會自動識別并將其納入管理。例如…

Oracle APEX 利用卡片實現翻轉(方法一)

目錄 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 1. 創建PL/SQL動態內容區域 2. 添加 CSS 實現翻轉效果 3. 添加動態操作 (Dynamic Action) 4. 看效果 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 正面&#xff1a; 顯示員工姓名 (EN…

Gradio全解11——Streaming:流式傳輸的視頻應用(1)——FastRTC:Python實時通信庫

Gradio全解11——Streaming&#xff1a;流式傳輸的視頻應用&#xff08;1&#xff09;——FastRTC&#xff1a;Python實時通信庫前言第11章 Streaming&#xff1a;流式傳輸的視頻應用11.1 FastRTC&#xff1a;Python實時通信庫11.1.1 WebRTC協議與FastRTC介紹1. WebRTC協議的概…

一文學會二叉搜索樹,AVL樹,紅黑樹

文章目錄二叉搜索樹查找插入刪除AVL樹概念插入旋轉AVL驗證紅黑樹概念插入檢測二叉搜索樹 也稱二叉排序樹或二叉查找樹 二叉搜索樹&#xff1a;可以為空&#xff0c;若不為空滿足以下性質 ?1&#xff0c;非空左子樹小于根節點的值 ?2&#xff0c;非空右子大于根節點的值 ?3…

Android實戰進階 - 啟動頁

場景&#xff1a;當啟動頁處于倒計時階段&#xff0c;用戶將其切換為后臺的多任務卡片狀態&#xff0c;倒計時會繼續執行&#xff0c;直到最后執行相關邏輯&#xff08;一般會跳轉引導頁、進入主頁等&#xff09; 期望&#xff1a;而綜合市場來看&#xff0c;一般我們期望的是當…

無標記點動捕技術:重塑展廳展館的沉浸式數字交互新時代

在元宇宙浪潮的持續推進下&#xff0c;虛擬數字人正逐漸成為連接虛實世界的重要媒介。在展廳展館中&#xff0c;數字人不僅能夠扮演導覽員、講解員角色&#xff0c;更可通過情感化交互提升參觀體驗&#xff0c;使文化傳播更具感染力和沉浸感。虛擬人的引入&#xff0c;為傳統展…

輕松Linux-7.Ext系列文件系統

天朗氣清&#xff0c;惠風和煦&#xff0c;今日無事&#xff0c;遂來更新。 1.概述 總所周知&#xff0c;我們存的數據都是在一個叫硬盤的東西里面&#xff0c;這個硬盤又像個黑盒&#xff0c;這章就來簡單解析一下Linux中文件系統。 現在我們用的大都是固態硬盤&#xff0c;…

Matlab機器人工具箱使用4 蒙特卡洛法繪制工作區間

原理&#xff1a;利用rand隨機數&#xff0c;給各個關節設置隨機關節變量&#xff0c;通過正運動學得到末端位姿變換矩陣&#xff0c;然后利用變換矩陣2三維坐標標記出末端坐標&#xff0c;迭代多次就可以構成點云。教程視頻&#xff1a;【MATLAB機器人工具箱10.4 機械臂仿真教…

【項目】在AUTODL上使用langchain實現《紅樓夢》知識圖譜和RAG混合檢索(三)知識圖譜和路由部分

首先在數據集 - 開放知識圖譜下載紅樓夢的知識圖譜&#xff0c;這個網站上有各種各樣的知識圖譜&#xff0c;可以挑你感興趣的做( ? ?ω?? ) 這個知識圖譜的作者們已經將三元組抽取出來了&#xff0c;我們可以直接用&#xff0c;如果你對三元組是如何生成的感興趣&#xf…

pycharm 最新版上一次編輯位置

2025nipycharm方法一&#xff1a;用快捷鍵&#xff08;最方便&#xff09;跳回上一次編輯位置&#xff1a;Windows/Linux: Ctrl Alt ←macOS: ? Option ←跳到前一次位置&#xff1a;Windows/Linux: Ctrl Alt →macOS: ? Option →方法二&#xff1a;顯示工具欄按鈕在…

前端性能監控與優化:從 Lighthouse 到 APM

在當今競爭激烈的數字環境中&#xff0c;用戶對Web應用性能的要求日益提高。一個緩慢或響應遲鈍的應用不僅會流失用戶&#xff0c;更可能損害品牌形象和商業價值。因此&#xff0c;前端性能的監控與優化已成為前端開發不可或缺的關鍵環節。本文將深入探討從基礎的性能評估工具L…

TC_Motion多軸運動-電子齒輪

目錄 電子齒輪 【基本概念】 【應用示例】 【開發總結】 END 電子齒輪 【基本概念】 定義:通過軟件方法實現機械齒輪的速比調節功能(兩個軸成線性比例旋轉) 優點 免維護,告別機械損耗 易調節,任意修改齒輪比 精度高,無機械背隙 應用場景 多臺電機拖動同一負載,要求多臺…

CentOS 7 下載教程

訪問阿里云鏡像站 阿里巴巴開源鏡像站 選擇centos 點這個 選擇7版本 進入isos目錄 點這個 選擇這個版本 因為這個鏡像的日期更新 推薦下載 DVD 版&#xff1a;包含完整系統和常用軟件&#xff0c;無需額外聯網安裝組件Minimal 版&#xff1a;精簡版&#xff0c;僅包含基礎系…