• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    如何操作Redis和zookeeper实现分布式锁

    如何操作Redis和zookeeper实现分布式锁

    在分布式场景下,有很多种情况都需要实现最终一致性。在设计远程上下文的领域事件的时候,为了保证最终一致性,在通过领域事件进行通讯的方式中,可以共享存储(领域模型和消息的持久化数据源),或者做全局XA事务(两阶段提交,数据源可分开),也可以借助消息中间件(消费者处理需要能幂等)。通过Observer模式来发布领域事件可以提供很好的高并发性能,并且事件存储也能追溯更小粒度的事件数据,使各个应用系统拥有更好的自治性。

    1.分布式锁

    分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个tomcat应用,在执行定时任务时就会遇到同一任务可能执行多次的情况,我们可以借助分布式锁,保证在同一时间只有一个tomcat应用执行了定时任务。

    2.分布式锁的实现方式

    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来监控节点的变化,从剩下的节点的找到最小的序列节点,获取分布式锁,执行相应处理,依次类推......

    感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

    您可能感兴趣的文章:
    • C# 实现Zookeeper分布式锁的参考示例
    • 分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
    • ZooKeeper 实现分布式锁的方法示例
    • 浅谈Java(SpringBoot)基于zookeeper的分布式锁实现
    • 浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)
    • zookeeper实现分布式锁
    • java使用zookeeper实现的分布式锁示例
    • 分析ZooKeeper分布式锁的实现
    上一篇:redis执行redis命令的方法教程
    下一篇:Redis实现分布式锁的几种方法总结
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    如何操作Redis和zookeeper实现分布式锁 如何,操作,Redis,和,zookeeper,