Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

  一男人站在楼顶准备跳楼,楼下有个劝解员拿个喇叭准备劝解

  劝解员:兄弟,别跳

  跳楼人:我不想活了

  劝解员:你想想你媳妇

  跳楼人:媳妇跟人跑了

  劝解员:你还有兄弟

  跳楼人:就是跟我兄弟跑的

  劝解员:你想想你家孩子

  跳楼人:孩子是他俩的

  劝解员:死吧,妈的你活着也没啥价值了

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

前言

  关于锁,相信大家都不陌生,一般我们用其在多线程环境中控制对共享资源的并发访问

  单服务下,用 JDK 中的 synchronized 或 Lock 的实现类可实现对共享资源的并发访问

  分布式服务下,JDK 中的锁就显得力不从心了,分布式锁也就应运而生了

  分布式锁的实现方式有很多,常见的有如下几种

    基于 MySQL,利用行级悲观锁(select ... for update)

    基于 Redis,利用其 (setnx + expire) 或 set 

    基于 Zookeeper,利用其临时目录和事件回调机制

  具体的实现细节就不展开了,网上资料很多

  看下文之前最好先看下:Redisson 分布式锁实现之前置篇 → Redis 的发布/订阅 与 Lua,方便更好的理解下文

分布式锁的特点

  可以类比 JDK 中的锁

  互斥

    不仅要保证同个服务中不同线程的互斥,还需要保证不同服务间、不同线程的互斥

    如何处理互斥,是自旋、还是阻塞 ,还是其他 ?

  超时

    锁超时设置,防止程序异常奔溃而导致锁一直存在,后续同把锁一直加不上

  续期

    程序具体执行的时长无法确定,所以过期时间只能是个估值,那么就不能保证程序在过期时间内百分百能运行完

    所以需要进行锁续期,保证业务能够正常执行完

  可重入

    可重入锁又名递归锁,是指同一个线程在外层方法已经获得锁,再进入该线程的中层或内层方法会自动获取锁

    简单点来说,就是同个线程可以反复获取同一把锁

  专一释放

    通俗点来讲:谁加的锁就只有它能释放这把锁

    为什么会出现这种错乱释放的问题了,举个例子就理解了

      线程 T1 对资源 lock_zhangsan 加了锁,由于某些原因,加锁业务还未执行完,锁过期自动释放了,此时线程 T2 对资源 lock_zhangsan 加锁成功

      T2 执行业务的时候,T1 业务执行完后释放资源 lock_zhangsan 的锁,结果把 T2 加的锁给释放了

  公平与非公平

    公平锁:多个线程按照申请锁的顺序去获得锁,所有线程都在队列里排队,这样就保证了队列中的第一个先得到锁

    非公平锁:多个线程不按照申请锁的顺序去获得锁,而是同时直接去尝试获取锁

    JDK 中的 ReentrantLock 就有公平和非公平两种实现,有兴趣的可以去看看它的源码

    多数情况下用的是非公平锁,但有些特殊情况下需要用公平锁

 

  很多小伙伴觉得:引入一个简单的分布式锁,有必要考虑这么多吗?

  虽然绝大部分情况下,我们的程序都是在跑正常流程,但不能保证异常情况 100% 跑不到,出于健壮性考虑,异常情况都需要考虑到

  下面我们就来看看 Redisson 是如何实现这些特点的

Redisson 实现分布式锁

  关于 Redisson,更多详细信息可查看官方文档

  Redisson 是 Redis 官方推荐的 ,它提供了非常丰富的功能,其中就包括本文关注的分布式锁

  环境准备

    简单示例开始之前,我们先看下环境;版本不同,会有一些差别

    JDK:1.8

    Redis:3.2.8

    Redisson:3.13.6

  简单示例

    先将 Redis 信息配置给 Redisson,创建出 RedissonClient

    Redis 的部署方式不同,Redisson 配置模式也会不同,详细信息可查看:Configuration

    我们就配置最简单的 Single instance mode 

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

    RedissonClient 创建出来后,就可以通过它来获取锁

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

    完整示例代码:redisson-demo

  接下来我们从源码层面一起看看 Redisson 具体是如何实现分布式锁的特点的

客户端创建

  客服端的创建过程中,会生成一个 id 作为唯一标识,用以区分分布式下不同节点中的客户端

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyppdw.html