一、为什么我们要用分布式锁?
比如说你做一个秒杀活动,在单机情况下,我们可以使用 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大星 | 文