Fork me on GitHub

【Zookeeper】分布式锁

一、概述

  • 分布式锁解决方案(目的:为了保证在分布式领域中共享数据安全问题)
  • 数据库实现分布式锁(不推荐、效率特别低)
  • 基于Redis实现分布式锁setNx (非常麻烦考虑死锁、释放问题) 、redission分布式锁
  • 基于Zookeeper实现分布式锁(强烈推荐)
  • SpringCloud内置实现全局锁(冷门)实现起来非常简单,使用临时节点释放锁(效率最高)、失效时间容易控制

  1. 分布式锁(产生的原因:因为服务器产生集群)
  2. 在单台服务器上如何生成订号( 保证唯一) UUId、时间戳、(大公司)redis
  3. 为什么要用redis去生成订单号 提前生成好150万订单号,存放在redis中,当客户端下单的之后,直接取redis获取对应的订单号即可,因为redis本身是单线程,如果redis还只剩下50万个订单号的时候,有继续在生成100万个订单号。
  4. 如果在集群的环境下使用UUId、时间戳能够保证订单号唯一性问题?不能

实现原理

  1. 多个jvm同时在zookeeper上创建同一个相同的节点(/lock) ,因为zookeeper节点是唯一的,如果是唯一的话,那么同时如果有多个客户端创建相同的节点/lock的话,最终只有看谁能够快速的抢资源,谁就能创建/lock节点,这个时候节点类型应该使用临时类型。
  2. 如果jvm1已经创建节点成功,那么这个时候jvm2、jvm3创建的节点时候,会报该/lock节点已经存在。这个时候jvm2和jvm3进行等待。如果jvm1现在已经程序已经执行完毕的话,
  3. Zookeepre如何实现释放锁?如果jvm1现在已经程序已经执行完毕的话,当前jvm1的ZK已经关闭当前Session会话。
  4. Zookeepre如何获取锁?看谁请求创建节点快,谁就可以拿到锁。
  5. 这时候jvm2和jvm3使用Watcher (事件通知)获取/lock已经被删除,这时候重新进入到获取请求。
  6. 如果程序一直不处理完,可能导致死锁,可以设置有效期,看业务情况,60秒,zk连接不要强制关闭,百分百延迟,直接调用close,产生延迟的概率非常小。

实现代码

Lock代码

posted @ 2019-09-14 23:53  这个世界~  阅读(230)  评论(0编辑  收藏  举报