如果有客户端1、客户端2等N个客户端争抢一个 Zookeeper 分布式锁。大致如下:
1: 大家都是上来直接创建一个锁节点下的一个接一个的临时有序节点
2: 如果自己不是第一个节点,就对自己上一个节点加监听器
3: 只要上一个节点释放锁,自己就排到前面去了,相当于是一个排队机制。
而且用临时顺序节点的另外一个用意就是,如果某个客户端创建临时顺序节点之后,不小心自己宕机了也没关系, Zookeeper 感知到那个客户端宕机,会自动删除对应的临时顺序节点,相当于自动释放锁,或者是自动取消自己的排队。
而且用临时顺序节点的另外一个用意就是,如果某个客户端创建临时顺序节点之后,不小心自己宕机了也没关系, Zookeeper 感知到那个客户端宕机,会自动删除对应的临时顺序节点,相当于自动释放锁,或者是自动取消自己的排队。
几个需要注意的地方如下:
-
死锁问题: 锁不能因为意外就变成死锁,所以要用 ZK 的临时节点,客户端连接失效了,锁就自动释放了。
-
锁等待问题: 锁有排队的需求,所以要 ZK 的顺序节点。
-
锁管理问题: 一个使用使用释放了锁,需要通知其他使用者,所以需要用到监听。
-
监听的羊群效应: 比如有 1000 个锁竞争者,锁释放了,1000 个竞争者就得到了通知,然后判断,最终序号最小的那个拿到了锁。其它 999 个竞争者重新注册监听。这就是羊群效应,出点事,就会惊动整个羊群。应该每个竞争者只监听自己前面的那个节点。比如 2 号释放了锁,那么只有 3 号得到了通知。