使用zookeeper作为分布式锁以及设计一种通知监听模式
- 1、创建实例
- /**
* 初始化单例的便捷方法
*/
- public static void init() {
- getInstance();
- }
- /**
* 获取单例
* @return
*/
- public static ZooKeeperSession getInstance() {
- return Singleton.getInstance();
- }
- /**
* 封装单例的静态内部类
* @author Administrator
*
*/
- private static class Singleton {
- private static ZooKeeperSession instance;
- static {
- instance = new ZooKeeperSession();
- }
- public static ZooKeeperSession getInstance() {
- return instance;
- }
- }
- zookeeper server,创建会话的时候,是异步去进行的,所以要给一个监听器,说告诉我们什么时候才是真正完成了跟zk server的连接。
- public ZooKeeperSession() {
- // 去连接zookeeper server,创建会话的时候,是异步去进行的
- // 所以要给一个监听器,说告诉我们什么时候才是真正完成了跟zk server的连接
- try {
- this.zookeeper = new ZooKeeper("192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181", 50000, new ZooKeeperWatcher());
- // 给一个状态CONNECTING,连接中
- System.out.println(zookeeper.getState());
- try {
- // CountDownLatch
- // java多线程并发同步的一个工具类
- // 会传递进去一些数字,比如说1,2 ,3 都可以
- // 然后await(),如果数字不是0,那么久卡住,等待
- // 其他的线程可以调用coutnDown(),减1
- // 如果数字减到0,那么之前所有在await的线程,都会逃出阻塞的状态
- // 继续向下运行
- connectedSemaphore.await();
- } catch(InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("ZooKeeper session established......");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
* 建立zk session的watcher
* @author Administrator
*
*/
- private class ZooKeeperWatcher implements Watcher {
- public void process(WatchedEvent event) {
- System.out.println("Receive watched event: " + event.getState());
- if(KeeperState.SyncConnected == event.getState()) {
- connectedSemaphore.countDown();
- }
- }
- }
**********************************************************************************************************
- /**
* 获取分布式锁
* @param productId
*/
- public void acquireDistributedLock(Long productId) {
- String path = "/product-lock-" + productId;
- try { /**
ZooDefs.Ids.OPEN_ACL_UNSAFE标识节点path的接入权限。
ZooDefs.Ids.OPEN_ACL_UNSAFE展开如下:
public final ArrayList<ACL> OPEN_ACL_UNSAFE = new ArrayList<ACL>(
Collections.singletonList(new ACL(Perms.ALL, ANYONE_ID_UNSAFE)));
其中ACL类是一个bean,包含两个参数如下:
private int perms;
private org.apache.zookeeper.data.Id id;
CreateMode类型分为4种
1.PERSISTENT--持久型
2.PERSISTENT_SEQUENTIAL--持久顺序型
3.EPHEMERAL--临时型
4.EPHEMERAL_SEQUENTIAL--临时顺序型
1、2种类型客户端断开后不会消失
3、4种类型客户端断开后超时时间内没有新的连接节点将会消息
- **/
- zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- System.out.println("success to acquire lock for product[id=" + productId + "]");
- } catch (Exception e) {
- // 如果那个商品对应的锁的node,已经存在了,就是已经被别人加锁了,那么就这里就会报错
- // NodeExistsException
- int count = 0;
- while(true) {
- try {
- Thread.sleep(1000);
- zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- } catch (Exception e2) {
- count++;
- System.out.println("the " + count + " times try to acquire lock for product[id=" + productId + "]......");
- continue;
- }
- System.out.println("success to acquire lock for product[id=" + productId + "] after " + count + " times try......");
- break;
- }
- }
- }
- /**
* 释放掉一个分布式锁
* @param productId
*/
- public void releaseDistributedLock(Long productId) {
- String path = "/product-lock-" + productId;
- try {
- zookeeper.delete(path, -1);
- System.out.println("release the lock for product[id=" + productId + "]......");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
**********************************************************************************************************
2、实例应用
- // 加代码,在将数据直接写入redis缓存之前,应该先获取一个zk的分布式锁
- ZooKeeperSession zkSession = ZooKeeperSession.getInstance();
- zkSession.acquireDistributedLock(productId);
- // 获取到了锁
- // 先从redis中获取数据
- ProductInfo existedProductInfo = cacheService.getProductInfoFromReidsCache(productId);
- if(existedProductInfo != null) {
- // 比较当前数据的时间版本比已有数据的时间版本是新还是旧
- try {
- Date date = sdf.parse(productInfo.getModifiedTime());
- Date existedDate = sdf.parse(existedProductInfo.getModifiedTime());
- if(date.before(existedDate)) {
- System.out.println("current date[" + productInfo.getModifiedTime() + "] is before existed date[" + existedProductInfo.getModifiedTime() + "]");
- return;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("current date[" + productInfo.getModifiedTime() + "] is after existed date[" + existedProductInfo.getModifiedTime() + "]");
- } else {
- System.out.println("existed product info is null......");
- }
- try {
- Thread.sleep(10 * 1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- cacheService.saveProductInfo2LocalCache(productInfo);
- System.out.println("===================获取刚保存到本地缓存的商品信息:" + cacheService.getProductInfoFromLocalCache(productId));
- cacheService.saveProductInfo2ReidsCache(productInfo);
- // 释放分布式锁
- zkSession.releaseDistributedLock(productId);
使用zookeeper作为分布式锁以及设计一种通知监听模式的更多相关文章
- zookeeper 实现分布式锁安全用法
zookeeper 实现分布式锁安全用法 标签: zookeeper sessionExpire connectionLoss 分布式锁 背景 ConnectionLoss 链接丢失 SessionE ...
- java就业指南 zookeeper分布式系统 zookeeper实现分布式锁 有用
目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个 分布式系统都无法同时满足一致性(Consistency).可用性 ...
- Redis、Zookeeper实现分布式锁——原理与实践
Redis与分布式锁的问题已经是老生常谈了,本文尝试总结一些Redis.Zookeeper实现分布式锁的常用方案,并提供一些比较好的实践思路(基于Java).不足之处,欢迎探讨. Redis分布式锁 ...
- 基于Zookeeper的分布式锁(干干干货)
原文地址: https://juejin.im/post/5df883d96fb9a0163514d97f 介绍 为什么使用锁 锁的出现是为了解决资源争用问题,在单进程环境下的资源争夺可以使用 JDK ...
- zookeeper实现分布式锁服务
A distributed lock base on zookeeper. zookeeper是hadoop下面的一个子项目, 用来协调跟hadoop相关的一些分布式的框架, 如hadoop, hiv ...
- [ZooKeeper.net] 3 ZooKeeper的分布式锁
基于ZooKeeper的分布式锁 ZooKeeper 里实现分布式锁的基本逻辑: 1.zookeeper中创建一个根节点(Locks),用于后续各个客户端的锁操作. 2.想要获取锁的client都在L ...
- 基于 Zookeeper 的分布式锁实现
1. 背景 最近在学习 Zookeeper,在刚开始接触 Zookeeper 的时候,完全不知道 Zookeeper 有什么用.且很多资料都是将 Zookeeper 描述成一个“类 Unix/Linu ...
- zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- 基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
随机推荐
- [Algorithm] Max Chars Problem
// --- Directions // Given a string, return the character that is most // commonly used in the strin ...
- 去掉amcharts4图表上的logo
引用了amcharts的图表工具,但右下角会显示amcharts 的图形LOGO,如下图: 而且每个图表上都有这个代码.看了一下代码里,找到这些LOGO,发现都有如下特征: aria-labelled ...
- App自动化-python-Unittest框架
TestCase: 一段Testcase代码示例: # -*- coding: utf-8 -*- ''' Created on 2019-6-27 @author: adminstrator ''' ...
- 解决Spring AOP Controller 不生效
在spring-mvc.xml文件中,进行以下配置,就可以实现在Controller中, 方法一:最简单的,在spring-mvc.xml配置文件中,添加以下语句 spring-mvc.xml < ...
- 封装Vue组件的一些技巧
封装Vue组件的一些技巧 本文同步在个人博客shymean.com上,欢迎关注 写Vue有很长一段时间了,除了常规的业务开发之外,也应该思考和反思一下封装组件的正确方式.以弹窗组件为例,一种实现是在需 ...
- Linq to XML - C#生成XML
1.System.Xml.XmlDocument XML file转成字符串 string path3 = @"C:\Users\test.xml"; XmlDocument ...
- 蓝桥 log大侠
标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...
- JVM GC之垃圾收集器
简述 如果说收集算法时内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.这里我们讨论的垃圾收集器是基于JKD1.7之后的Hotspot虚拟机,这个虚拟机包含的所有收集器如图: Serial 收集 ...
- Qt5.11.2 VS2015编译activemq发送程序 _ITERATOR_DEBUG_LEVEL错误和崩溃解决
1.问题描述: 运行环境是 win10 64位系统,开发环境是VS2015 ,Qt 5.11.2.开发activemq发送程序,遇到问题 (1)Qt5AxContainer.lib error LNK ...
- HTML语义化是什么?为什么要语义化?
HTML语义化HTML的语义化总结为: 用最恰当的标签来标记内容. 该如何理解呢?比如需要加入一个标题,这个标题的字体比正文的要大写,还要加粗.能够实现这种效果的方法有很多,比如用CSS样式进行渲染. ...