redis:基于redis实现分布式锁,setnx和setex(一)

1.分布式锁是什么?

  • 分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一 种锁实现
  • 如果不同的系统或同一个系统的不同主机之间共享了某一个资源时,往往通过互斥来防止彼此干扰

2.分布锁设计目的

  • 可以保证在分布式部署的应用集群中,同个方法在同 操作只能被一 台机器上的一 个线程执行。

 3.分布式锁实现方案分析

  • 在获取锁的时候使用setnx,(Set If Not Exist)当且仅当key不存在进行set,成功返回1,失败返回0
  • 判断是否成功set了锁,成功就为锁设置超时时间,使用setex
  • 执行结束释放锁,判断当前线程是否获得了锁,获得则del

4.本地起两个服务节点作为演示。演示代码如下:

  1. 本文采用定时调度模拟线程去获取锁(链接:详解Scheduled定时调度
  2. 使用-Dserver.port=9527,-Dserver.port=9528开启多个节点
@Component
public class RedisLock {

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${server.port}")
    private String port;

    private Boolean absent;

    @Scheduled(cron = "0/5 * * * * *")
    public void lock() {

        String lock = "LockNxExJob";

        try {

            // 获取锁
            absent = redisTemplate.opsForValue ().setIfAbsent (lock, port);

            if (!absent) {
                System.out.println (String.format ("获取锁失败!被%s拿走", redisTemplate.opsForValue ().get (lock)));
            } else {
                redisTemplate.opsForValue ().set (lock, port, 3600);
                System.out.println (String.format ("获取锁成功!值为:%s", redisTemplate.opsForValue ().get (lock)));
            }

        } catch (Exception e) {
            e.printStackTrace ();
        } finally {
            // 释放锁
            if (absent) redisTemplate.delete (lock);
        }

    }

}

9527端口控制台输出:

  • 获取锁失败!被9528拿走
  • 获取锁成功!值为:9527
  • 获取锁成功!值为:9527
  • 获取锁成功!值为:9527

9528端口控制台输出:

  • 获取锁成功!值为:9528
  • 获取锁失败!被9527拿走
  • 获取锁失败!被9527拿走
  • 获取锁失败!被9527拿走

5.问题剖析:

  • 在setnx成功之后,服务发生了宕机,此时没能完成设置超时时间,此key则一直存在,无法得到释放,其他服务节点则永远无法获得锁,出现死锁。

6.解决方案:

7.总结

  • 简单的基于redis分布式锁完成。如果当一个线程未能获得锁,需要 在次重新获取锁,可以采取递归的方式,在获取锁失败重新回调lock方法。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值