zookeeper实现分布式锁实战
分布式锁
分布式锁(多服务共享锁) 在分布式的部署环境下,通过锁机制来让多客户端互斥的对共享资源进行访问。
对于一个分布式系统中同一个方法,如果多个线程同时访问,对数据库的修改会产生错误,所以就需要在整个分布式系统上的多线程同时访问造成数据错误的代码段或者说方法上加分布式锁。
分布式锁的种类
- 基于数据库本身的锁
- 基于redis中的setnx的锁
- 基于zookeeper的分布式锁
zookeeper分布式锁
因为zookeeper的结构是一个树形的结构,所以使用zokeeper实现分布式锁的方式就是,建立锁就是建立一个文件夹,然后多线程要获取分布式锁的过程中,可以在这个锁(也就是文件夹)下创建一个个有序的文件,代表获取锁的多线程的顺序。
如下实现原理:
zookeeper实战
使用docker安装安装zookeeper
docker run --name some-zookeeper -d --privileged=true -p 2181:2181 -p 8080:8080 zookeeper:latest
启动后:访问http://ip:8080/commands
代表启动成功
创建springboot项目并引入依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
实现zookeeper分布式锁
@RestController public class zookeeperTest { @RestController public class TestControl { private int a = 10; @RequestMapping("/test") public String test() throws Exception { //设置zk的客户端重试策略 每隔5秒重试一次,最多10次 RetryPolicy policy = new ExponentialBackoffRetry(5000, 10); //创建zk客户端 链接zookeeper服务器 CuratorFramework client = CuratorFrameworkFactory.builder().connectString("ip(改成自己的):2181").retryPolicy(policy).build(); //创建与zookeeper服务器的连接 client.start(); //声明锁的对象,本质就是ZK顺序临时节点 final InterProcessMutex mutex = new InterProcessMutex(client, "/lock/shoe"); try { //请求锁,创建锁 mutex.acquire(); if(a>0){ Thread.sleep(500); return "你抢到了"+(a--); }else{ return "商品已无"; } } catch (Exception e) { e.printStackTrace(); }finally { mutex.release(); } return "null"; } } }
启动项目使用jmeter测试
- 创建线程组并设置线程数为15
2. 创建http请求
3. 创建结果树(便于查看请求结果)
- 查看zookeper的树结构的节点
可以看出文件树是有序的,也就是需要执行一个之后再执行其他的,并发度降低了,所以适合并发小的程序。