使用redis和zookeeper实现分布式锁
2017-07-14 00:00
796 查看
1.分布式锁
分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个tomcat应用,在执行定时任务时就会遇到同一任务可能执行多次的情况,我们可以借助分布式锁,保证在同一时间只有一个tomcat应用执行了定时任务。
2.分布式锁的实现方式
1.使用redis的setnx()和expire()
2.使用redis的getset()
3.使用zookeeper的创建节点node
4.使用zookeeper的创建临时序列节点
3.使用redis的setnx()和expire()来实现分布式锁
定义注解类:
定时任务增加注解@Lockable:
定义一个aop切面LockAspect,使用@Around处理所有注解为@Lockable的方法,通过连接点确认此注解是用在方法上,通过方法获取注解信息,使用setIfAbsent来判断是否获取分布式锁,如果没有获取分布式锁,直接返回;如果获取到分布式锁,通过expire设置过期时间,并调用指定方法。
4.使用redis的getset()来实现分布式锁
此方法使redisTemplate.boundValueOps(key).getAndSet(value)的方法,如果返回空,表示获取了分布式锁;如果返回不为空,表示分布式锁已经被其他程序占用
5.使用zookeeper的创建节点node
使用zookeeper创建节点node,如果创建节点成功,表示获取了此分布式锁;如果创建节点失败,表示此分布式锁已经被其他程序占用(多个程序同时创建一个节点node,只有一个能够创建成功)
6.使用zookeeper的创建临时序列节点
使用zookeeper创建临时序列节点来实现分布式锁,适用于顺序执行的程序,大体思路就是创建临时序列节点,找出最小的序列节点,获取分布式锁,程序执行完成之后此序列节点消失,通过watch来监控节点的变化,从剩下的节点的找到最小的序列节点,获取分布式锁,执行相应处理,依次类推......更多资源尽在Redis缓存技术交流组:288724942
分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个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 学习(10)流程图解使用redis实现分布式锁
- 使用redis和zookeeper实现分布式锁
- 使用Redis实现分布式锁
- Java使用Redis实现分布式锁
- 浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)
- 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)
- 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
- 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)
- 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
- 使用redis和zookeeper实现分布式锁
- 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)
- Java之——redis并发读写锁,使用Redisson实现分布式锁
- 如何操作Redis和zookeeper实现分布式锁
- 使用redis和zookeeper实现分布式锁
- 分布式锁实现方案(REDIS,ZOOKEEPER,TAIR)
- 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)
- 使用redis实现分布式锁(在集群环境下让任务排队执行)
- 使用 Redis 实现分布式锁(转)
- 使用ThinkPHP扩展,实现Redis的CURD操作。