方案1:
算法思路:利用名稱唯一性,加鎖操作時,只需要所有客戶端一起創建/test/Lock節點,只有一個創建成功,成功者獲得鎖。解鎖時,只需刪除/test/Lock節點,其余客戶端再次進入競爭創建節點,直到所有客戶端都獲得鎖。
特點:這種方案的正確性和可靠性是ZooKeeper機制保證的,實現簡單。缺點是會產生“驚群”效應,假如許多客戶端在等待一把鎖,當鎖釋放時候所有客戶端都被喚醒,僅僅有一個客戶端得到鎖。
方案2:
算法思路:臨時順序節點實現共享鎖
客戶端調用create()方法創建名為“locknode/guid-lock-”的節點,需要注意的是,這里節點的創建類型需要設置為EPHEMERAL_SEQUENTIAL。
客戶端調用getChildren(“locknode”)方法來獲取所有已經創建的子節點,同時在這個節點上注冊上子節點變更通知的Watcher。
客戶端獲取到所有子節點path之后,如果發現自己在步驟1中創建的節點是所有節點中序號最小的,那么就認為這個客戶端獲得了鎖。
如果在步驟3中發現自己並非是所有子節點中最小的,說明自己還沒有獲取到鎖,就開始等待,直到下次子節點變更通知的時候,再進行子節點的獲取,判斷是否獲取鎖。
特點:適合小集群分布式。集群大會耗時嚴重。
方案3:
算法思路:臨時順序節點實現共享鎖的改進實現
對於加鎖操作,可以讓所有客戶端都去/lock目錄下創建臨時順序節點,如果創建的客戶端發現自身創建節點序列號是/lock/目錄下最小的節點,則獲得鎖。否則,監視比自己創建節點的序列號小的節點(比自己創建的節點小的最大節點),進入等待。
對於解鎖操作,只需要將自身創建的節點刪除即可。
特點:利用臨時順序節點來實現分布式鎖機制其實就是一種按照創建順序排隊的實現。這種方案效率高,避免了“驚群”效應,多個客戶端共同等待鎖,當鎖釋放時只有一個客戶端會被喚醒。

開源包menagerie :對方案3的一個封裝,直接拿來用,貌似11年以后沒更新過------》不建議使用。最新github:https://github.com/sfines/menagerie。
重頭戲來了,我們curator包已經封裝好了,直接使用即可。-------------》建議使用。具體curator實現原理+測試,后續再分析。
