Zookeeper 分布式锁

在分布式场景中,采用传统的锁并不能解决跨进程并发的问题,所以需要引入一个分布式锁,来解决多个节点之间的访问控制

一、Zookeeper如何解决分布式锁

基于Zookeeper的两种特性来实现分布式锁:

  • 第一种,使用唯一节点特性实现分布式锁
  • 第二种,使用有序节点实现分布式锁

二、使用唯一节点特性实现分布式锁

多个应用程序去抢占锁资源时,只需要在指定节点上创建一个 /Lock 节点,由于Zookeeper中节点的唯一性特性,使得只会有一个用户成功创建 /Lock 节点,剩下没有创建成功的用户表示竞争锁失败。

问题:惊群效应

惊群效应”,简单来说就是如果存在许多的客户端在等待获取锁,当成功获取到锁的进程释放该节点后,所有处于等待状态的客户端都会被唤醒(等待的方式自然是使用Watcher机制来监听/lock节点的删除事件),这个时候zookeeper在短时间内发送大量子节点变更事件给所有待获取锁的客户端,然后实际情况是只会有一个客户端获得锁。如果在集群规模比较大的情况下,会对zookeeper服务器的性能产生比较的影响。

三:使用有序节点实现分布式锁

因此为了解决惊群效应,可以采用Zookeeper的有序节点特性来实现分布式锁。

每个客户端都往指定的节点下注册一个临时有序节点,越早创建的节点,节点的顺序编
号就越小,那么我们可以判断子节点中最小的节点设置为获得锁。如果自己的节点不是所有子节点中最小的,意味着还没有获得锁。

不同于第一种方式性在于,每个节点只需要监听比自己小的前一个节点,当比自己小的节点删除以后,客户端会收到watcher事件,此时再次判断自己的节点是不是所有子节点中最小的,如果是则获得锁,否则就不断重复这个过程,这样就不会导致羊群效应,因为每个客户端只需要监控前一个节点

有序节点实现分布式锁的流程

四:Curator实现分布式锁

curator对于锁这块做了一些封装,curator提供了InterProcessMutex 这样一个api。

具体的使用方法如下:

1、引入pom

<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>

2、CuratorConfig

@Configuration
public class CuratorConfig {@Bean
public CuratorFramework curatorFramework(){CuratorFramework curatorFramework=CuratorFrameworkFactory
.builder()
.connectString("127.0.0.1:2181")
.sessionTimeoutMs(15000)
.connectionTimeoutMs(20000)
.retryPolicy(new ExponentialBackoffRetry(1000,10))
.build();
curatorFramework.start();
return curatorFramework;
}
}

3、 Controller,使用锁机制

@Scope(scopeName = "prototype")
@RestController
@RequestMapping("/goods-stock")
public class GoodsStockController {@Autowired
IGoodsStockService goodsStockService;
@Autowired
CuratorFramework curatorFramework;
@GetMapping("{goodsNo}")
public String purchase(@PathVariable("goodsNo")Integer goodsNo) throws
Exception {QueryWrapper<GoodsStock> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("goods_no",goodsNo);
InterProcessMutex lock=new
InterProcessMutex(curatorFramework,"/Lock");
try {lock.acquire(); //抢占锁(阻塞)
GoodsStock goodsStock=goodsStockService.getOne(queryWrapper);
Thread.sleep(new Random().nextInt(1000));
if(goodsStock==null){return "指定商品不存在";
}
if(goodsStock.getStock().intValue()<1){return "库存不够";
}
goodsStock.setStock(goodsStock.getStock() - 1);
boolean res = goodsStockService.updateById(goodsStock);
if (res) {return "抢购书籍:" + goodsNo + "成功";
}
return "抢购失败";
}finally {lock.release(); //释放锁
}
}
}

注:前面已经理解的Zookeeper实现分布式锁的原理,以及基于Curator完成了分布式锁的使用, Curator就是基于代码实现了这一过程。

Zookeeper 分布式锁相关推荐

  1. [转载] zookeeper 分布式锁服务

    转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...

  2. zookeeper 分布式锁原理

    zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...

  3. 分布式锁原理——redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  4. 关于分布式锁原理的一些学习与思考:redis分布式锁,zookeeper分布式锁

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 作者:队长给我球. 出处:https://w ...

  5. 分布式锁(一) Zookeeper分布式锁

    什么是Zookeeper? Zookeeper(业界简称zk)是一种提供配置管理.分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而 ...

  6. Zookeeper分布式锁的使用

    由于公司引入了dubbo+zookeeper框架,里面不可避免的引入的zookeeper分布式锁,所以自己大致了解了一下.由于是自己研究,有不正确的地方还请大佬批评指正. 首先先介绍一下自己对zook ...

  7. zookeeper 分布式锁服务

    分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那一层来挡.当大量的行锁.表锁.事务充斥着数据库的时候.一般web应用很多的瓶颈都在数据库上,这里给大家介绍的是减轻数据库锁负担的一种 ...

  8. zookeeper 分布式锁_关于redis分布式锁,zookeeper分布式锁原理的一些学习与思考

    编辑:业余草来源:https://www.xttblog.com/?p=4946 首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法 ...

  9. redis cluster 分布式锁_关于分布式锁原理的一些学习与思考redis分布式锁,zookeeper分布式锁...

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  10. zookeeper分布式锁原理及实现

    前言 本文介绍下 zookeeper方式 实现分布式锁 原理简介 zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且 ...

最新文章

  1. k8S中的MySQL如何扩容_Kubernetes的etcd多节点扩容实战技巧
  2. (转)【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!...
  3. SAP Spartacus Register 页面为空白的解决方案
  4. 自定义EventSource(一)EventCounter
  5. camel Java to xml_java – 当Camel从XML文件加载路由时,在注册表中找不到Bean
  6. csstd超出部分用...替换
  7. 【转】关于PHP的header(P3P: CP=CURa……)
  8. 基于CentOS7.2安装Kubernetes-v1.2
  9. jquery18 css() : 样式的操作
  10. 设置javadoc模板
  11. java语言的编译器命令_Java编译器命令行功能
  12. malloc用户态内存分配
  13. three.js纹理贴图不显示
  14. idea自动排版html,idea怎么格式化代码?
  15. 图像处理基本库的学习笔记5--公共数据集,PASCAL VOC数据集,NYUD V2数据集的简介与提取,COCO2017,医学影像数据集汇总
  16. latex sty文件设置
  17. biopython中文指南_Biopython的列表和限制类型
  18. MSIL 教程(一)
  19. 有幸被评为微软全球最有价值专家(MVP)
  20. java连接打印机_JAVA实现连接本地打印机并打印文件的实现代码

热门文章

  1. Linux网络通信——TCP通信流程
  2. SHA1加密算法(spring boot)
  3. 四十以上软件开发人员没有出路了吗?
  4. deallocate mysql_MySQL 预处理语句prepare、execute、deallocate的使用
  5. cocos2dx骨骼动画Armature源码分析(三)
  6. 微信web开发者工具使用教程
  7. 六、SAR(合成孔径雷达)数据样本标注
  8. N1变砖有救N1 eMMC 镜像,理论用于TTL救砖 ,使用ddbr恢复官改系统救砖方法
  9. @Async 使用发现的问题
  10. 2017noip提高组初赛试卷