理论篇:

Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手.

看完官方的文档之后, 发现Curator主要解决了三类问题:

  • 封装ZooKeeper client与ZooKeeper server之间的连接处理;
  • 提供了一套Fluent风格的操作API;
  • 提供ZooKeeper各种应用场景(recipe, 比如共享锁服务, 集群领导选举机制)的抽象封装.

Curator列举的ZooKeeper使用过程中的几个问题 
初始化连接的问题: 在client与server之间握手建立连接的过程中, 如果握手失败, 执行所有的同步方法(比如create, getData等)将抛出异常 
自动恢复(failover)的问题: 当client与一台server的连接丢失,并试图去连接另外一台server时, client将回到初始连接模式 
session过期的问题: 在极端情况下, 出现ZooKeeper session过期, 客户端需要自己去监听该状态并重新创建ZooKeeper实例 . 
对可恢复异常的处理:当在server端创建一个有序ZNode, 而在将节点名返回给客户端时崩溃, 此时client端抛出可恢复的异常, 用户需要自己捕获这些异常并进行重试 
使用场景的问题:Zookeeper提供了一些标准的使用场景支持, 但是ZooKeeper对这些功能的使用说明文档很少, 而且很容易用错. 在一些极端场景下如何处理, zk并没有给出详细的文档说明. 比如共享锁服务, 当服务器端创建临时顺序节点成功, 但是在客户端接收到节点名之前挂掉了, 如果不能很好的处理这种情况, 将导致死锁.

Curator主要从以下几个方面降低了zk使用的复杂性: 
重试机制:提供可插拔的重试机制, 它将给捕获所有可恢复的异常配置一个重试策略, 并且内部也提供了几种标准的重试策略(比如指数补偿). 
连接状态监控: Curator初始化之后会一直的对zk连接进行监听, 一旦发现连接状态发生变化, 将作出相应的处理. 
zk客户端实例管理:Curator对zk客户端到server集群连接进行管理. 并在需要的情况, 重建zk实例, 保证与zk集群的可靠连接 
各种使用场景支持:Curator实现zk支持的大部分使用场景支持(甚至包括zk自身不支持的场景), 这些实现都遵循了zk的最佳实践, 并考虑了各种极端情况.

Curator通过以上的处理, 让用户专注于自身的业务本身, 而无需花费更多的精力在zk本身.

实操篇:

CuratorFrameworkFactory类提供了两个方法, 一个工厂方法newClient, 一个构建方法build. 使用工厂方法newClient可以创建一个默认的实例, 而build构建方法可以对实例进行定制. 当CuratorFramework实例构建完成, 紧接着调用start()方法, 在应用结束的时候, 需要调用close()方法.  CuratorFramework是线程安全的. 在一个应用中可以共享同一个zk集群的CuratorFramework.

核心对象CuratorFramework的创建如下:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework client = CuratorFrameworkFactory.builder().connectString("").sessionTimeoutMs(5000).connectionTimeoutMs(5000).retryPolicy(retryPolicy).build();
client.start();

需要使用分布式锁的地方,代码如下:

String lockOn= "test";
InterProcessMutex mutex = new InterProcessMutex(curatorFramework,lockOn);
boolean locked =mutex.acquire(0,TimeUnit.SECONDS);

//finally部分  mutex.release();

分布式锁常用于定时任务,使用自定义注解,使用spring aspect around, 在真正的代码执行之前尝试获取锁,获取不到直接退出,获取到锁的,执行具体业务,代码如下:

@Aspect
public class DistributedLockAspect{@Pointcut("@annotation(com.**.**.DistributedLock")public void methodAspect(){};  @Around("methodAspect()")public Object execute(ProceedingJoinPoint joinPoint) throws Exception{String lockPath = "/opt/zookeeper/lock";InterProcessMutex mutex = new InterProcessMutex(cruatorFramework,lockPath);try{boolean locked = mutex.acquire(0,TimeUnit.SECONDS);if(!locked){return null;}else{return joinPoint.proceed();}}catch(Exception e){e.printStackTrace();}finally{mutex.release();}}
} 

自定义注解:

1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface DistributedLock{
4    String lockPath();
5 }

注意事项:

1.  CuratorFramework对象建议在应用中做单例处理,在具体使用处 注入使用, 并在应用结束前销毁,代码如下:

@Configration
public class CuratorConfigration{@Bean    public CuratorFramework initCuratorFramework(){//忽略 // 参照前面 CuratorFramework 对象创建部分
    }
}

2. 在aspect部分将curatorFramework对象进行关闭

@PreDestroy
public void destroy(){CloseableUtils.closeQuietly(curatorFramework);
}

转载于:https://www.cnblogs.com/xifenglou/p/10455553.html

springboot整合curator实现分布式锁相关推荐

  1. springboot整合curator实现分布式锁模拟抢购场景

    文章目录 1.环境说明 2.maven依赖 3.代码实现 3.1.Redis 3.1.1.配置文件 3.1.2.redisTemplate配置 3.2.Curator 3.1.1.配置文件 3.1.2 ...

  2. springboot整合redis实现分布式锁思想

    思路 所有响应获取锁的线程都先尝试往redis中创建一个缓存数据,所有线程的key必须相同.使用的是redis的setnx命令.就只有一个线程能够创建成功,创建成功的线程就成功获取锁. 没有获取锁的线 ...

  3. springboot整合redisson实现分布式锁

    一.介绍Redisson Redisson是Redis官方推荐的Java版的Redis客户端(Jedis.letture也是官方推荐的java版本redis客户端程序).它提供的功能非常多,也非常强大 ...

  4. 分布式架构-ZK客户端工具Curator框架分布式锁及基本使用

    分布式架构-基于Curator分布式锁及基本使用 一.Curator Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作 ...

  5. Apache Curator之分布式锁原理(二)

    本文主要讲解如下内容: 为什么要使用分布式锁? 分布式锁特性! 分布式锁的实现方式有哪些? Curator分布式锁原理 Curator分布式锁实现类UML及相关类的介绍 基于Redis,数据库实现分布 ...

  6. Curator实现分布式锁的基本原理

    curator是Netflix公司开源的一个ZooKeeper客户端封装.curator 对于锁这块做了一些封装,curator 提供了InterProcessMutex 这样一个 api.除了分布式 ...

  7. zookeeper操作封装——curator使用分布式锁使用

    文章目录 1. 基本操作 1.1 建立连接 1.2 建立结点 1.3 查询结点 查询数据 查询子结点 查看结点信息 1.4 修改结点 普通修改 带乐观锁的修改 1.5 删除 删除单个结点 删除带子结点 ...

  8. 干货,springboot自定义注解实现分布式锁详解

    背景 在互联网的很多场景下,会产生资源竞争,如果是单机环境,简单加个锁就能解决问题:但是在集群环境下(分布式环境),多个客户端在一个很短的时间内竞争同一服务端资源(如抢购场景),或者同一客户端重复提交 ...

  9. Curator实现分布式锁的基本原理-LockInternals.internalLockLoop

    // 循环等待来激活分布式锁,实现锁的公平性 private boolean internalLockLoop(long startMillis, Long millisToWait, String ...

最新文章

  1. 英语发音规则---N字母
  2. python在财务上的应用-python 与财务
  3. 【阿里云课程】如何从零开始完成第一个GAN项目
  4. js获取下月时间_js 获取日期时间段
  5. 带彩色字体的man pages(debian centos)
  6. HTML+CSS+JS实现 ❤️卡通人物吃水果游戏❤️
  7. Spring @Autowired Annotation
  8. Python:数据类型
  9. 一个新基民的感叹:人心不足蛇吞象
  10. nopcommerce笔记3 还可以控制什么
  11. Mac基础操作:如何用启动台来查看和打开App
  12. 利用Bitvise SSH Client与proxifier实现SSH全局代理
  13. Pycharm画图中文显示报错:UserWarning: Glyph 20013 (\N{CJK UNIFIED IDEOGRAPH-4E2D}) missing from current font.
  14. MyEclipse共享项目到SVN服务器 .
  15. 笔记本计算机没有没有显示无线网络连接,笔记本没有无线网络连接,教您笔记本没有无线网络连接...
  16. 有3个学生3门功课成绩s={‘Teddy‘:[100,90,90], ‘Sandy‘:[98,91,80],‘Elmo‘:[90,90,83]} 要求输出每个学生的姓名,平均成绩(结果保留1位小
  17. MNE溯源fieldtrip官网教程
  18. PHP微信支付 curl请求https://api.mch.weixin.qq.com/pay/unifiedorder 返回空的解决方案
  19. 发了一篇小红书,阅读量破了20W...
  20. [开发工具] STM32算法的翅膀之MATLAB

热门文章

  1. mysql dump xtrabackup_MySQL之备份和恢复(msyqldump、LVM、xtrabackup)
  2. 有关计算机组装和拆卸的说法,有关计算机组装论文
  3. Android开发网络连接超时
  4. opencv转单通道python_在OpenCv(Python)中查找单通道图像的目录
  5. thymeleaf表达式优先级及表达式简单说明
  6. ORA-01502-对应的快速解决办法(索引或这类索引的分区处于不可用状态)
  7. java 将bean转化为map,将javabean转化为map对象
  8. win7旗舰恢复出厂设置_iphone12怎么恢复出厂设置 iphone12还原所有设置方法介绍
  9. Kubernetes集群搭建之Etcd集群配置篇
  10. AIR3.0针对移动设备的高性能渲染方案