使用redis,zookeeper实现分布式锁
1.分布式锁
分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个tomcat应用,在执行定时任务时就会遇到同一任务可能执行多次的情况,我们可以借助分布式锁,保证在同一时间只有一个tomcat应用执行了定时任务。
2.分布式锁的实现方式
1.使用redis的setnx()和expire()
2.使用redis的getset()
3.使用zookeeper的创建节点node
4.使用zookeeper的创建临时序列节点
3.使用redis的setnx()和expire()来实现分布式锁
- setnx(key,value) 如果key不存在,设置为当前key的值为value;如果key存在,直接返回。
- expire()来设置超时时间
定义注解类:
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Lockable{
- // redis缓存key
- String key();
- // redis缓存key中的数据
- String value() default "";
- // 过期时间(秒),默认为一分钟
- long expire() default 60;
- }
定时任务增加注解@Lockable:
- @Lockable(key = "DistributedLock:dealExpireRecords")
- public void dealExpireRecords() {
- }
定义一个aop切面LockAspect,使用@Around处理所有注解为@Lockable的方法,通过连接点确认此注解是用在方法上,通过方法获取注解信息,使用setIfAbsent来判断是否获取分布式锁,如果没有获取分布式锁,直接返回;如果获取到分布式锁,通过expire设置过期时间,并调用指定方法。
- @Component
- @Slf4j
- @Aspect
- public class LockAspect {
- @Autowired
- private RedisTemplate redisTemplate;
- @Around("@annotation(com.records.aop.Lockable)")
- public Object distributeLock(ProceedingJoinPoint pjp) {
- Object resultObject = null;
- //确认此注解是用在方法上
- Signature signature = pjp.getSignature();
- if (!(signature instanceof MethodSignature)) {
- log.error("Lockable is method annotation!");
- return resultObject;
- }
- MethodSignature methodSignature = (MethodSignature) signature;
- Method targetMethod = methodSignature.getMethod();
- //获取注解信息
- Lockable lockable = targetMethod.getAnnotation(Lockable.class);
- String key = lockable.key();
- String value = lockable.value();
- long expire = lockable.expire();
- // 分布式锁,如果没有此key,设置此值并返回true;如果有此key,则返回false
- boolean result = redisTemplate.boundValueOps(key).setIfAbsent(value);
- if (!result) {
- //其他程序已经获取分布式锁
- return resultObject;
- }
- //设置过期时间,默认一分钟
- redisTemplate.boundValueOps(key).expire(expire, TimeUnit.SECONDS);
- try {
- resultObject = pjp.proceed(); //调用对应方法执行
- } catch (Throwable throwable) {
- throwable.printStackTrace();
- }
- return resultObject;
- }
- }
4.使用redis的getset()来实现分布式锁
此方法使redisTemplate.boundValueOps(key).getAndSet(value)的方法,如果返回空,表示获取了分布式锁;如果返回不为空,表示分布式锁已经被其他程序占用
5.使用zookeeper的创建节点node
使用zookeeper创建节点node,如果创建节点成功,表示获取了此分布式锁;如果创建节点失败,表示此分布式锁已经被其他程序占用(多个程序同时创建一个节点node,只有一个能够创建成功)
6.使用zookeeper的创建临时序列节点
使用zookeeper创建临时序列节点来实现分布式锁,适用于顺序执行的程序,大体思路就是创建临时序列节点,找出最小的序列节点,获取分布式锁,程序执行完成之后此序列节点消失,通过watch来监控节点的变化,从剩下的节点的找到最小的序列节点,获取分布式锁,执行相应处理,依次类推......更多资源共享尽在Redis缓存技术交流组:288724942
使用redis,zookeeper实现分布式锁的更多相关文章
- Redis与Zookeeper实现分布式锁的区别
Redis实现分布式锁 1.根据lockKey区进行setnx(set not exist,如果key值为空,则正常设置,返回1,否则不会进行设置并返回0)操作,如果设置成功,表示已经获得锁,否则并没 ...
- 【连载】redis库存操作,分布式锁的四种实现方式[一]--基于zookeeper实现分布式锁
一.背景 在电商系统中,库存的概念一定是有的,例如配一些商品的库存,做商品秒杀活动等,而由于库存操作频繁且要求原子性操作,所以绝大多数电商系统都用Redis来实现库存的加减,最近公司项目做架构升级,以 ...
- 基于zookeeper实现分布式锁和基于redis实现分布所的区别
1,实现方式不同 zookeeper实现分布式锁:通过创建一个临时节点,创建的成功节点的服务则抢占到分布式锁,可做业务逻辑.当业务逻辑完成,连接中断,节点消失,继续下一轮的锁的抢占. redis实现分 ...
- Redis、Zookeeper实现分布式锁——原理与实践
Redis与分布式锁的问题已经是老生常谈了,本文尝试总结一些Redis.Zookeeper实现分布式锁的常用方案,并提供一些比较好的实践思路(基于Java).不足之处,欢迎探讨. Redis分布式锁 ...
- 基于Redis的简单分布式锁的原理
参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的 ...
- zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- redis客户端、分布式锁及数据一致性
Redis Java客户端有很多的开源产品比如Redission.Jedis.lettuce等. Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持:Redis ...
- 基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- Redis实现的分布式锁和分布式限流
随着现在分布式越来越普遍,分布式锁也十分常用,我的上一篇文章解释了使用zookeeper实现分布式锁(传送门),本次咱们说一下如何用Redis实现分布式锁和分布限流. Redis有个事务锁,就是如下的 ...
- 10分钟看懂!基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
随机推荐
- 说一说Java的Unsafe类
最近在看Java并发包的源码,发现了神奇的Unsafe类,仔细研究了一下,在这里跟大家分享一下. Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛 ...
- mysql的存储过程,函数,事件,权限,触发器,事务,锁,视图,导入导出
1.创建过程 1.1 简单创建 -- 创建员工表 DROP TABLE IF EXISTS employee; CREATE TABLE employee( id int auto_increment ...
- Maven+SSM框架搭建【spring+springmvc+mybatis】
本案例用到:ssm[spring+springmvc+mybatis]框架 数据库:mysql (推荐使用mysql 或者 sqlserver .oracle太大,一般大型项目才会用到) 开发工具: ...
- 算法第四版 coursera公开课 普林斯顿算法 ⅠⅡ部分 Robert Sedgewick主讲《Algorithms》
这是我在网上找到的资源,下载之后上传到我的百度网盘了. 包含两部分:1:算法视频的种子 2:字幕 下载之后,请用迅雷播放器打开,因为迅雷可以直接在线搜索字幕. 如果以下链接失效,请在下边留言,我再更新 ...
- faster-rcnn 结构杂谈
faster-rcnn结构图: (只截取了最难理解的部分) 这个网络看似很复杂,但是理解了其中关键的层,就基本可以掌握这个结构了.要看源码!!要看源码!!要看源码 !!重要的事情说三遍. 关键的层: ...
- javascript中的数组对象
1.创建数组的三种方式: 1.1 var 数组名=[元素1,元素2,元素3...]; 例如: var arr1=[1,2,3,4]; 1.2 var 数组名=new Array(元素1,元素2,元素3 ...
- markdown最基本的几种语法
1.标题 # 相当于<h1></h1> ## 相当于<h2></h2> ### 相当于<h3></h3> #### 相当于< ...
- Mybatis的mapper代理开发dao方法
看完了之前的mybatis原始的dao开发方法是不是觉得有点笨重,甚至说没有发挥mybatis 作为一个框架的优势.总结了一下,原始的dao方法有以下几点不足之处 dao接口实现方法中存在大量的模板方 ...
- LxmlLinkExtractor类参数解析
LxmlLinkExtractor LxmlLinkExtractor 是一种强大的链接提取器,使用他能很方便的进行选项过滤,他是通过xml中强大的HTMLParser实现的 源代码如下: class ...
- jmeter入门(02)测试报告各项指标含义
一.名词定义(时间单位ms) 1.聚合报告 Sample:本次测试场景共运行多少个请求: Average:平均响应时间: Median:统计意义上的响应时间中值: 90% line:所有线程中90%的 ...