一、為什麼我們要用分佈式鎖?
比如說你做一個秒殺活動,在單機情況下,我們可以使用 Java 基礎中的互斥鎖來保證對庫存共享變量進行多線程同步訪問,防止出現“超賣”現象。
但是,隨著業務量擴大,分佈式集群,Nginx負載均衡,傳統的方式根本不能保障庫存共享變量的可見性。
你最常用的是什麼分佈式鎖? 單選
0
人0%
A.Mysql 分佈式鎖
0
人0%
B.Redis 分佈式鎖
0
人0%
C.ZooKeeper 分佈式鎖
二、Zookeeper 分佈式鎖
相信不少小夥伴使用 Redis 分佈式鎖來解決“超賣”問題,使用 Redis 分佈式鎖會有一個問題,如果業務處理時間大於分佈式鎖失效時間呢??有一種解決方案是 Redisson 分佈式鎖,感興趣的可以深入研究。我們這裡介紹一下 ZooKeeper 分佈式鎖。
1、認識 Zookeeper(以下簡稱 zk)
相信很多 Java 小夥伴 認識 zk 是從 dubbo 開始,使用 zk 做註冊中心,注意這是一個考點哦,dubbo 是怎樣把服務註冊到 zk 上,詳細描述下。
① zk 通俗解釋
我們可以把 zk 看做文件目錄系統,就像我們 windos 下的 D 盤文件一樣,我們可以對文件進行增刪改查,而且 zk 提供監聽通知機制。
② zk 節點
zk 文件目錄系統裡存儲節點,節點可以分為 4 種類型
- 持久化節點(zk 客戶端斷開,數據還在)
- 持久化順序節點
- 臨時節點(zk 客戶端斷開,數據消失)
- 臨時順序節點
③ windows 下簡單玩玩 zk
【方式一】
✔ 傻瓜式安裝,唯一需要注意的點是複製一份zoo_sample.cfg,改名 zoo.cfg。
為啥呢,這是因為 /bin 目錄下的 zkEnv.cmd 中掃描的是 zoo.cfg
✔ 雙擊 zkServer.cmd,啟動 zk 服務,默認是 127.0.0.1:2181
✔ 雙擊 zkCli.cmd ,啟動一個 zk 客戶端,這個時候你就可以 創建 zk 節點了
創建節點的命令
//-s為有序節點,-e為臨時節點,path 路徑帶上斜杆/
create [-s] [-e] path data
【方式二】
Idea 插件,注意這種方式操作臨時節點顯示會有延遲
2、zk 可以用來做什麼???
- 服務註冊與訂閱(共用節點)
- 分佈式通知(監聽 znode)
- 服務命名(znode 特性)
- 數據訂閱、發佈(watcher)
- 分佈式鎖(臨時節點)✔
3、分佈式鎖(重點)
① zk 有 4 種節點方式,選擇哪一種合適?
當然選擇 臨時順序節點
好處一,客戶端斷開,臨時節點消失,釋放鎖;好處二隻需監聽上一個節點。
注意:有序節點生成 path 會自動生成後綴編碼,如下
② 分佈式鎖實現原理
- 每個客戶端往/locks下創建臨時有序節點/locks/lock_,創建成功後/locks下面會有每個客戶端對應的節點 ,如/locks/lock_0000000001
- 客戶端取得/locks下的子節點,並進行排序,判斷排在最前面的是否是自己,如果自己在第一位,表示獲取鎖成功
- 果自己的鎖節點不在第一位,則監聽自己前一個節點的鎖節點,例如鎖節點 lock_0000000002,那麼監聽鎖節點 lock_0000000001
- 當前一個鎖節點 lock_0000000001 對應的客戶端執行完成,釋放鎖,將會觸發監聽客戶端 lock_0000000002的邏輯
- 監聽客戶端重新執行第2步邏輯,判斷自己是否獲取了鎖
③ 用 Curator 實現分佈式鎖
Curator 是 原生 zk api 的一層封裝,是最流行的 zk 客戶端
@Python大星 | 文