1. 1、创建实例
  1. /**
    * 初始化单例的便捷方法
    */
  1. public static void init() {
  2. getInstance();
  3. }

  

  1. /**
    * 获取单例
    * @return
    */
  1. public static ZooKeeperSession getInstance() {
  2. return Singleton.getInstance();
  3. }

  

  1. /**
    * 封装单例的静态内部类
    * @author Administrator
    *
    */
  1. private static class Singleton {
  2.  
  3. private static ZooKeeperSession instance;
  4.  
  5. static {
  6. instance = new ZooKeeperSession();
  7. }
  8.  
  9. public static ZooKeeperSession getInstance() {
  10. return instance;
  11. }
  12.  
  13. }

 

  1. zookeeper server,创建会话的时候,是异步去进行的,所以要给一个监听器,说告诉我们什么时候才是真正完成了跟zk server的连接。
  1. public ZooKeeperSession() {
  2. // 去连接zookeeper server,创建会话的时候,是异步去进行的
  3. // 所以要给一个监听器,说告诉我们什么时候才是真正完成了跟zk server的连接
  4. try {
  5. this.zookeeper = new ZooKeeper("192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181", 50000, new ZooKeeperWatcher());
  6. // 给一个状态CONNECTING,连接中
  7. System.out.println(zookeeper.getState());
  8.  
  9. try {
  10. // CountDownLatch
  11. // java多线程并发同步的一个工具类
  12. // 会传递进去一些数字,比如说1,2 ,3 都可以
  13. // 然后await(),如果数字不是0,那么久卡住,等待
  14.  
  15. // 其他的线程可以调用coutnDown(),减1
  16. // 如果数字减到0,那么之前所有在await的线程,都会逃出阻塞的状态
  17. // 继续向下运行
  18.  
  19. connectedSemaphore.await();
  20. } catch(InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23.  
  24. System.out.println("ZooKeeper session established......");
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }

  

 

  1. /**
    * 建立zk session的watcher
    * @author Administrator
    *
    */
  1. private class ZooKeeperWatcher implements Watcher {
  2.  
  3. public void process(WatchedEvent event) {
  4. System.out.println("Receive watched event: " + event.getState());
  5. if(KeeperState.SyncConnected == event.getState()) {
  6. connectedSemaphore.countDown();
  7. }
  8. }
  9.  
  10. }

  

**********************************************************************************************************

  1. /**
    * 获取分布式锁
    * @param productId
    */
  1. public void acquireDistributedLock(Long productId) {
  2. String path = "/product-lock-" + productId;
  3.  
  4. 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种类型客户端断开后超时时间内没有新的连接节点将会消息

  1.                **/
  2. zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  3. System.out.println("success to acquire lock for product[id=" + productId + "]");
  4. } catch (Exception e) {
  5. // 如果那个商品对应的锁的node,已经存在了,就是已经被别人加锁了,那么就这里就会报错
  6. // NodeExistsException
  7. int count = 0;
  8. while(true) {
  9. try {
  10. Thread.sleep(1000);
  11. zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  12. } catch (Exception e2) {
  13. count++;
  14. System.out.println("the " + count + " times try to acquire lock for product[id=" + productId + "]......");
  15. continue;
  16. }
  17. System.out.println("success to acquire lock for product[id=" + productId + "] after " + count + " times try......");
  18. break;
  19. }
  20. }
  21. }

 

  1. /**
    * 释放掉一个分布式锁
    * @param productId
    */
  1. public void releaseDistributedLock(Long productId) {
  2. String path = "/product-lock-" + productId;
  3. try {
  4. zookeeper.delete(path, -1);
  5. System.out.println("release the lock for product[id=" + productId + "]......");
  6. } catch (Exception e) {
  7. e.printStackTrace();
  8. }
  9. }

**********************************************************************************************************

2、实例应用

  1.           // 加代码,在将数据直接写入redis缓存之前,应该先获取一个zk的分布式锁
  2. ZooKeeperSession zkSession = ZooKeeperSession.getInstance();
  3. zkSession.acquireDistributedLock(productId);
  4.  
  5. // 获取到了锁
  6. // 先从redis中获取数据
  7. ProductInfo existedProductInfo = cacheService.getProductInfoFromReidsCache(productId);
  8.  
  9. if(existedProductInfo != null) {
  10. // 比较当前数据的时间版本比已有数据的时间版本是新还是旧
  11. try {
  12. Date date = sdf.parse(productInfo.getModifiedTime());
  13. Date existedDate = sdf.parse(existedProductInfo.getModifiedTime());
  14.  
  15. if(date.before(existedDate)) {
  16. System.out.println("current date[" + productInfo.getModifiedTime() + "] is before existed date[" + existedProductInfo.getModifiedTime() + "]");
  17. return;
  18. }
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. System.out.println("current date[" + productInfo.getModifiedTime() + "] is after existed date[" + existedProductInfo.getModifiedTime() + "]");
  23. } else {
  24. System.out.println("existed product info is null......");
  25. }
  26.  
  27. try {
  28. Thread.sleep(10 * 1000);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32.  
  33. cacheService.saveProductInfo2LocalCache(productInfo);
  34. System.out.println("===================获取刚保存到本地缓存的商品信息:" + cacheService.getProductInfoFromLocalCache(productId));
  35. cacheService.saveProductInfo2ReidsCache(productInfo);
  36.  
  37. // 释放分布式锁
  38. zkSession.releaseDistributedLock(productId);

  

使用zookeeper作为分布式锁以及设计一种通知监听模式的更多相关文章

  1. zookeeper 实现分布式锁安全用法

    zookeeper 实现分布式锁安全用法 标签: zookeeper sessionExpire connectionLoss 分布式锁 背景 ConnectionLoss 链接丢失 SessionE ...

  2. java就业指南 zookeeper分布式系统 zookeeper实现分布式锁 有用

    目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个 分布式系统都无法同时满足一致性(Consistency).可用性 ...

  3. Redis、Zookeeper实现分布式锁——原理与实践

    Redis与分布式锁的问题已经是老生常谈了,本文尝试总结一些Redis.Zookeeper实现分布式锁的常用方案,并提供一些比较好的实践思路(基于Java).不足之处,欢迎探讨. Redis分布式锁 ...

  4. 基于Zookeeper的分布式锁(干干干货)

    原文地址: https://juejin.im/post/5df883d96fb9a0163514d97f 介绍 为什么使用锁 锁的出现是为了解决资源争用问题,在单进程环境下的资源争夺可以使用 JDK ...

  5. zookeeper实现分布式锁服务

    A distributed lock base on zookeeper. zookeeper是hadoop下面的一个子项目, 用来协调跟hadoop相关的一些分布式的框架, 如hadoop, hiv ...

  6. [ZooKeeper.net] 3 ZooKeeper的分布式锁

    基于ZooKeeper的分布式锁 ZooKeeper 里实现分布式锁的基本逻辑: 1.zookeeper中创建一个根节点(Locks),用于后续各个客户端的锁操作. 2.想要获取锁的client都在L ...

  7. 基于 Zookeeper 的分布式锁实现

    1. 背景 最近在学习 Zookeeper,在刚开始接触 Zookeeper 的时候,完全不知道 Zookeeper 有什么用.且很多资料都是将 Zookeeper 描述成一个“类 Unix/Linu ...

  8. zookeeper的分布式锁

    实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...

  9. 基于Zookeeper的分布式锁

    实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...

随机推荐

  1. [Algorithm] Max Chars Problem

    // --- Directions // Given a string, return the character that is most // commonly used in the strin ...

  2. 去掉amcharts4图表上的logo

    引用了amcharts的图表工具,但右下角会显示amcharts 的图形LOGO,如下图: 而且每个图表上都有这个代码.看了一下代码里,找到这些LOGO,发现都有如下特征: aria-labelled ...

  3. App自动化-python-Unittest框架

    TestCase: 一段Testcase代码示例: # -*- coding: utf-8 -*- ''' Created on 2019-6-27 @author: adminstrator ''' ...

  4. 解决Spring AOP Controller 不生效

    在spring-mvc.xml文件中,进行以下配置,就可以实现在Controller中, 方法一:最简单的,在spring-mvc.xml配置文件中,添加以下语句 spring-mvc.xml < ...

  5. 封装Vue组件的一些技巧

    封装Vue组件的一些技巧 本文同步在个人博客shymean.com上,欢迎关注 写Vue有很长一段时间了,除了常规的业务开发之外,也应该思考和反思一下封装组件的正确方式.以弹窗组件为例,一种实现是在需 ...

  6. Linq to XML - C#生成XML

    1.System.Xml.XmlDocument  XML file转成字符串  string path3 = @"C:\Users\test.xml";  XmlDocument ...

  7. 蓝桥 log大侠

    标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...

  8. JVM GC之垃圾收集器

    简述 如果说收集算法时内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.这里我们讨论的垃圾收集器是基于JKD1.7之后的Hotspot虚拟机,这个虚拟机包含的所有收集器如图: Serial 收集 ...

  9. Qt5.11.2 VS2015编译activemq发送程序 _ITERATOR_DEBUG_LEVEL错误和崩溃解决

    1.问题描述: 运行环境是 win10 64位系统,开发环境是VS2015 ,Qt 5.11.2.开发activemq发送程序,遇到问题 (1)Qt5AxContainer.lib error LNK ...

  10. HTML语义化是什么?为什么要语义化?

    HTML语义化HTML的语义化总结为: 用最恰当的标签来标记内容. 该如何理解呢?比如需要加入一个标题,这个标题的字体比正文的要大写,还要加粗.能够实现这种效果的方法有很多,比如用CSS样式进行渲染. ...