springboot整合curator实现分布式锁
理论篇:
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实现分布式锁相关推荐
- 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 ...
- springboot整合redis实现分布式锁思想
思路 所有响应获取锁的线程都先尝试往redis中创建一个缓存数据,所有线程的key必须相同.使用的是redis的setnx命令.就只有一个线程能够创建成功,创建成功的线程就成功获取锁. 没有获取锁的线 ...
- springboot整合redisson实现分布式锁
一.介绍Redisson Redisson是Redis官方推荐的Java版的Redis客户端(Jedis.letture也是官方推荐的java版本redis客户端程序).它提供的功能非常多,也非常强大 ...
- 分布式架构-ZK客户端工具Curator框架分布式锁及基本使用
分布式架构-基于Curator分布式锁及基本使用 一.Curator Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作 ...
- Apache Curator之分布式锁原理(二)
本文主要讲解如下内容: 为什么要使用分布式锁? 分布式锁特性! 分布式锁的实现方式有哪些? Curator分布式锁原理 Curator分布式锁实现类UML及相关类的介绍 基于Redis,数据库实现分布 ...
- Curator实现分布式锁的基本原理
curator是Netflix公司开源的一个ZooKeeper客户端封装.curator 对于锁这块做了一些封装,curator 提供了InterProcessMutex 这样一个 api.除了分布式 ...
- zookeeper操作封装——curator使用分布式锁使用
文章目录 1. 基本操作 1.1 建立连接 1.2 建立结点 1.3 查询结点 查询数据 查询子结点 查看结点信息 1.4 修改结点 普通修改 带乐观锁的修改 1.5 删除 删除单个结点 删除带子结点 ...
- 干货,springboot自定义注解实现分布式锁详解
背景 在互联网的很多场景下,会产生资源竞争,如果是单机环境,简单加个锁就能解决问题:但是在集群环境下(分布式环境),多个客户端在一个很短的时间内竞争同一服务端资源(如抢购场景),或者同一客户端重复提交 ...
- Curator实现分布式锁的基本原理-LockInternals.internalLockLoop
// 循环等待来激活分布式锁,实现锁的公平性 private boolean internalLockLoop(long startMillis, Long millisToWait, String ...
最新文章
- 英语发音规则---N字母
- python在财务上的应用-python 与财务
- 【阿里云课程】如何从零开始完成第一个GAN项目
- js获取下月时间_js 获取日期时间段
- 带彩色字体的man pages(debian centos)
- HTML+CSS+JS实现 ❤️卡通人物吃水果游戏❤️
- Spring @Autowired Annotation
- Python:数据类型
- 一个新基民的感叹:人心不足蛇吞象
- nopcommerce笔记3 还可以控制什么
- Mac基础操作:如何用启动台来查看和打开App
- 利用Bitvise SSH Client与proxifier实现SSH全局代理
- Pycharm画图中文显示报错:UserWarning: Glyph 20013 (\N{CJK UNIFIED IDEOGRAPH-4E2D}) missing from current font.
- MyEclipse共享项目到SVN服务器 .
- 笔记本计算机没有没有显示无线网络连接,笔记本没有无线网络连接,教您笔记本没有无线网络连接...
- 有3个学生3门功课成绩s={‘Teddy‘:[100,90,90], ‘Sandy‘:[98,91,80],‘Elmo‘:[90,90,83]} 要求输出每个学生的姓名,平均成绩(结果保留1位小
- MNE溯源fieldtrip官网教程
- PHP微信支付 curl请求https://api.mch.weixin.qq.com/pay/unifiedorder 返回空的解决方案
- 发了一篇小红书,阅读量破了20W...
- [开发工具] STM32算法的翅膀之MATLAB
热门文章
- mysql dump xtrabackup_MySQL之备份和恢复(msyqldump、LVM、xtrabackup)
- 有关计算机组装和拆卸的说法,有关计算机组装论文
- Android开发网络连接超时
- opencv转单通道python_在OpenCv(Python)中查找单通道图像的目录
- thymeleaf表达式优先级及表达式简单说明
- ORA-01502-对应的快速解决办法(索引或这类索引的分区处于不可用状态)
- java 将bean转化为map,将javabean转化为map对象
- win7旗舰恢复出厂设置_iphone12怎么恢复出厂设置 iphone12还原所有设置方法介绍
- Kubernetes集群搭建之Etcd集群配置篇
- AIR3.0针对移动设备的高性能渲染方案