什么是分布式锁

1.分布式锁分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个tomcat应用,在执行定时任务时就会遇到同一任务可能执行多次的情况,我们可以借助分布式锁,保证在同一时间只有一个tomcat应用执行了定时任务。2.分布式锁的实现方式(1).使用redis的setnx()和expire()(2)使用redis的getset()(3)使用zookeeper的创建节点node(4)使用zookeeper的创建临时序列节点3.使用redis的setnx()和expire()来实现分布式锁

作者:我在代码里遨游
链接:https://www.zhihu.com/question/62598701/answer/200098050
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值