加载中...
avatar
文章
42
标签
25
分类
21
首页
Java
Spring全家桶
  • Spring
  • SpringBoot
  • SpringCloud
JVM
源码
  • Mybatis
  • HashMap
归档
其他
  • 互联网电子书汇总
  • JAVA八股文指南
  • 历史
  • 相册
关于
Logo码农Stormling分布式系列(二) | Redisson分布式锁
搜索
首页
Java
Spring全家桶
  • Spring
  • SpringBoot
  • SpringCloud
JVM
源码
  • Mybatis
  • HashMap
归档
其他
  • 互联网电子书汇总
  • JAVA八股文指南
  • 历史
  • 相册
关于

分布式系列(二) | Redisson分布式锁

发表于2024-12-05|更新于2024-12-22|Redisson分布式
|总字数:902|阅读时长:3分钟|浏览量:

分布式锁

1、概述

  • Redisson 是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。
  • Redisson 的宗旨是:促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。

2、四个条件

为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:

  • 第一个:互斥性,在任何时刻,只有一个客户端能持有锁。
  • 第二个:不会发生死锁,即使有一个客户端在获取锁操作时候崩溃了,也能保证其他客户端能获取到锁。
  • 第三个:解铃还须系铃人,解锁加锁必须同一个客户端操作。
  • 第四个:加锁和解锁必须具备原子性

3、引入依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
</dependency>

4、配置类别

创建RedissonConfig 配置类
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedissonConfig {

    private String host;

    private String password;

    private String port;

    private int timeout = 3000;
    private static String ADDRESS_PREFIX = "redis://";

    /**
     * 自动装配
     *
     */
    @Bean
    RedissonClient redissonSingle() {
        Config config = new Config();

        if(!StringUtils.hasText(host)){
            throw new RuntimeException("host is  empty");
        }
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(ADDRESS_PREFIX + this.host + ":" + port)
                .setTimeout(this.timeout);
        if(StringUtils.hasText(this.password)) {
            serverConfig.setPassword(this.password);
        }
        return Redisson.create(config);
    }
}

配置 application.yml

spring:
    data:
        redis:
          host: 192.168.2.5
          port: 6379
          database: 0
          timeout: 1800000
          password:
          jedis:
            pool:
              max-active: 20 #最大连接数
              max-wait: -1    #最大阻塞等待时间(负数表示没限制)
              max-idle: 5    #最大空闲
              min-idle: 0 

5、代码实现

public void testLockRedisson() {
       // 1.获取锁 可重入锁
       RLock lock = redissonClient.getLock("lock1");
       // 2.加锁
       try {
           // 阻塞 默认过期30s  看门狗:自动续期
           lock.lock();
           // 设置过期 10s
           //lock.lock(10, TimeUnit.SECONDS);
           // 等待时间 、 设置过期时间
           // lock.tryLock(30, 10, TimeUnit.SECONDS);
           // 3.业务代码
           String value = redisTemplate.opsForValue().get("num");
           if (StringUtil.isBlank(value)) {
               return;
           }
           int num = Integer.parseInt(value);
           redisTemplate.opsForValue().set("num", String.valueOf(++num));
       } finally {
           //4.释放锁
           lock.unlock();
       }

   }

6、Redisson 看门狗

基于**`Redis`**的**`Redisson`**分布式可重入锁**`RLock` `Java`**对象实现了**`java.util.concurrent.locks.Lock`**接口。
如果负责储存这个分布式锁的**`Redisson`**节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现**锁死**的状态。为了避免这种情况的发生,**`Redisson`**内部提供了一个**监控锁的看门狗**,它的作用是在**`Redisson`**实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改**`Config.lockWatchdogTimeout来`**另行指定。

另外**Redisson还通过加锁的方法提供了leaseTime**的参数来指定加锁的时间。超过这个时间后锁便自动解开了。

看门狗原理:

只要线程一加锁成功,就会启动一个**`watch dog`**看门狗,它是一个**后台线程**,会每隔**10秒检查**一下,如果线程还持有锁,那么就会**不断的延长锁key**的生存时间。因此,**`Redisson`**就是使用**`watch dog`**解决了`锁过期释放,业务没执行完问题`。
  • 如果我们指定了锁的超时时间,就发送给**Redis**执行脚本,进行占锁,默认超时就是我们制定的时间,不会自动续期;
  • 如果我们未指定锁的超时时间,就使用 lockwatchdogTimeout= 30 * 1000【看门狗默认时间】
文章作者: stormling
文章链接: http://www.stormling.top/posts/50356.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 码农Stormling!
Redisson分布式
cover of previous post
上一篇
数据库系列(二) | Mybatis Plus 3.0+快速入门
Mybatis Plus 3.0+快速入门 官网:https://baomidou.com/ 参考教程:快速开始 最新版本:3.5.7 对应版本参考:JDK 8+ 、Maven or Gradle 1、简介MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 2、创建并初始化数据库2.1、创建数据库mybatis_plus 2.2、创建 User...
cover of next post
下一篇
分布式系列(一) | Redis分布式锁
Redis实现分布式锁 乐尚代驾学习笔记-Redis司机抢单分布式锁 1、setnx+过期时间实现 @Override public void testLock() { //从redis里面获取数据 //1 获取当前锁 setnx Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent("lock", "lock"); //2 如果获取到锁,从redis获取数据 数据+1 放回redis里面 if(ifAbsent) { //获取锁成功,执行业务代码 //1.先从redis中通过key num获取值 key提前手动设置 num 初始值:0 String value = redisTemplate.opsForValue().get("num"); //2.如果值为空则非法直接返回即可 if (StringUtils.isBlank(value)) { ...
相关推荐
cover
2024-12-03
分布式系列(一) | Redis分布式锁
Redis实现分布式锁 乐尚代驾学习笔记-Redis司机抢单分布式锁 1、setnx+过期时间实现 @Override public void testLock() { //从redis里面获取数据 //1 获取当前锁 setnx Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent("lock", "lock"); //2 如果获取到锁,从redis获取数据 数据+1 放回redis里面 if(ifAbsent) { //获取锁成功,执行业务代码 //1.先从redis中通过key num获取值 key提前手动设置 num 初始值:0 String value = redisTemplate.opsForValue().get("num"); //2.如果值为空则非法直接返回即可 if (StringUtils.isBlank(value)) { ...

评论
ValineGitalk
avatar
stormling
文章
42
标签
25
分类
21
Follow Me
公告
欢迎大家来到Stormling博客
目录
  1. 1. 分布式锁
    1. 1.1. 1、概述
    2. 1.2. 2、四个条件
    3. 1.3. 3、引入依赖
    4. 1.4. 4、配置类别
      1. 1.4.0.0.1. 创建RedissonConfig 配置类
  • 1.5. 5、代码实现
  • 1.6. 6、Redisson 看门狗
  • 最新文章
    面向八股文面试专场
    面向八股文面试专场2025-01-22
    【每日早报】-2025-01-21 - 星期二
    【每日早报】-2025-01-21 - 星期二2025-01-21
    规则引擎 Drools 8+ 快速入门
    规则引擎 Drools 8+ 快速入门2024-12-11
    数据库系列(二) | Mybatis Plus 3.0+快速入门
    数据库系列(二) | Mybatis Plus 3.0+快速入门2024-12-09
    分布式系列(二) | Redisson分布式锁
    分布式系列(二) | Redisson分布式锁2024-12-05
    ©2019 - 2025 By stormling
    码农Stormling程序员,关注公众号【码农Stormling】回复【面试】获取最全面试pdf
    搜索
    数据加载中