Redisson实现分布式锁示例

这篇具有很好参考价值的文章主要介绍了Redisson实现分布式锁示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、引入依赖

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

二、配置类

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @Author ZGM
 * @DateTime 2023/8/15
 * @description
 */
@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient(){
        // 配置,
        Config config = new Config();
        //单例模式
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
               // .setPassword("123456");
        //修改看门狗的默认时间30s到60s
        //config.setLockWatchdogTimeout(60000);
        // 创建RedissonClient对象
        return Redisson.create(config);
    }


    //这个只针对转化为string类型
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        //默认是JDK序列化  发现key和value前面都多了一串特殊字符
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(stringRedisSerializer);
        return template;
    }
}

三、实现类

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author ZGM
 * @DateTime 2023/8/15
 * @description
 */
@Service
@Slf4j
public class UserService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    public void test1() throws InterruptedException {
        //定义一个key
        String key = UUID.randomUUID().toString();

        // 占锁 没有拿到锁的会自动阻塞
        // watchDog 机制 : 锁自动加了默认30秒过期
        // 如果业务代码耗时长,锁也会自动续期
        RLock lock = redissonClient.getLock(key);

        //只有lock()和tryLock(5000, TimeUnit.MILLISECONDS)会触发看门狗机制
        Boolean isLocked = lock.tryLock(5000, TimeUnit.MILLISECONDS);
        if(!isLocked) {
           log.info("获取锁失败");
        }
        long a = System.currentTimeMillis();
        try {
            Thread.sleep(60000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        long b = System.currentTimeMillis();
        System.out.println(b-a);
    }

}

四、测试结果

可以下载redis desktop manager软件来查看redis里面存放的东西
Redisson实现分布式锁示例,分布式
红色框内的TTL值就是过期时间,默认-1,表示永不过期,指定过期时间后就变成你指定的值了。

上面的方法,我们让线程睡眠60S,代表我们的业务执行时间,在调用这个方法时,我们可以在
redis desktop manager软件上实时查看锁的过期时间,第一次过期时间为30S,10S后刷新过期时间为30S,也就是说,它每隔10S会检验这个锁是否释放,没有的话,会一直给你刷新锁的持有时间变为30S,直到任务完成。

五、看门狗机制

上面所说的自动刷新锁的持有时间,就是通过这个看门狗机制来实现的。它默认的锁的持有时间是30S,每隔30/3也就是10S会刷新锁的持有时间,我们也可以通过redisson的Config 类的config.setLockWatchdogTimeout(60000)来修改过期时间。实际上锁的持有时间就是lockWatchdogTimeout的值,只不过默认设置的30S而已,同样的,锁的刷新时间也是每隔lockWatchdogTimeout/3秒执行一次,如果设置的时间为60S,就是锁的过期时间为60S,每隔20S执行一次。
所谓的自动刷新,其实是在获取锁的时候,开了一个线程来监控这个锁,我们先按照默认的30S过期时间来计算,假设当前业务的执行时间在10S之内,在第10S时此线程监控到该锁已被正常释放,则不会刷新锁的过期时间,反之,在第10S时此线程监控到该锁仍被此线程持有,那也就是业务还未执行完,它就会帮你刷新过期时间。即使redis的服务器宕机了,也不会出现死锁,因为当它监控到异常时,也不会刷新过期时间,当redis的服务器恢复时,自动就把它删除了。

六、注意

注意:只有只有lock()和tryLock(waitTime, TimeUnit.MILLISECONDS)会触发看门狗机制,在这两个方法里我们都没有指定releaseTime,它默认值就是-1,然后才能自动触发看门狗机制,或者我们在调用获取锁的方法时直接指定releaseTime为-1,这样也可以触发看门狗机制,一定要注意这一点。
lock()会一直尝试获取锁,知道成功
tryLock(long time, TimeUnit unit),同样会一直尝试获取锁,但它有等待时间,超过这个时间就直接返回false,不在继续调用,我比较喜欢这个方法。

七、建议

看门狗机制虽然可以自动刷新锁的过期时间,用起来也非常方便,但并不是说,所有的方法,都应该开启此机制。因为启动此机制的同时,意味着会额外开启一个线程来监控它,那么就会占用CPU内存。少量线程的情况下,这部分内存占用可以忽略,当请求过多时,就占用比略高了,只能增加服务器,也就是增加成本了。

所以我建议是,在获取资源的方法里,不开启看门狗机制,比如,一个接口是返回个人信息的,那么我在调用时,由于某种原因导致锁已经释放,但业务还未执行完成,那么会报错,
信息如下:[Request processing failed; nested exception is java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: 62e61f35-6cd5-4fc2-849e-78ad649435e4 thread-id: 72] with root cause,我们直接捕获此异常,返回系统繁忙即可。

在更新或者保存资源的方法里,是可以开启看门狗机制的,这样虽然执行时间会稍微长一些,但最终会完成任务,不至于让用户重复操作。文章来源地址https://www.toymoban.com/news/detail-657636.html

到了这里,关于Redisson实现分布式锁示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot 集成 Redisson 实现分布式锁

            Redisson 是一种基于 Redis 的 Java 驻留集群的分布式对象和服务库,可以为我们提供丰富的分布式锁和线程安全集合的实现。在 Spring Boot 应用程序中使用 Redisson 可以方便地实现分布式应用程序的某些方面,例如分布式锁、分布式集合、分布式事件发布和订阅等。本篇

    2024年02月08日
    浏览(39)
  • 微服务系列文章之 Redisson实现分布式锁

    当我们在设计分布式锁的时候,我们应该考虑分布式锁至少要满足的一些条件,同时考虑如何高效的设计分布式锁,这里我认为以下几点是必须要考虑的。 1、互斥 在分布式高并发的条件下,我们最需要保证,同一时刻只能有一个线程获得锁,这是最基本的一点。 2、防止死

    2024年02月15日
    浏览(99)
  • 源码篇--Redisson 分布式锁lock的实现

    我们知道Redis 缓存可以使用setNx来作为分布式锁,但是我们直接使用setNx 需要考虑锁过期的问题;此时我们可以使用Redisson 的lock 来实现分布式锁,那么lock 内部帮我们做了哪些工作呢。 RedisConfig.java lock.lock() 阻塞获取 redis 锁,获取到锁之后继续向下执行业务逻辑; lockInterr

    2024年01月25日
    浏览(47)
  • 在Java项目中使用redisson实现分布式锁

    在Java项目中使用Redission自定义注解实现分布式锁: 添加Redission依赖项:在项目的pom.xml中添加Redission依赖项: 创建自定义注解:创建一个自定义注解来标记需要使用分布式锁的方法。例如,创建一个名为 @DistributedLock 的注解: 创建注解切面:创建一个切面类,通过AOP将注解

    2024年02月16日
    浏览(39)
  • 微服务系列文章之 Redisson实现分布式锁(3)

    1、技术架构 项目总体技术选型 2、加锁方式 该项目支持  自定义注解加锁  和  常规加锁  两种模式 自定义注解加锁 常规加锁 3、Redis部署方式 该项目支持四种Redis部署方式 该项目已经实现支持上面四种模式,你要采用哪种只需要修改配置文件 application.properties ,项目代码

    2024年02月16日
    浏览(40)
  • 微服务系列文章之 Redisson实现分布式锁(2)

    1、概念 很明显RLock是继承Lock锁,所以他有Lock锁的所有特性,比如lock、unlock、trylock等特性,同时它还有很多新特性:强制锁释放,带有效期的锁,。 2、RLock锁API 这里针对上面做个整理,这里列举几个常用的接口说明 RLock相关接口,主要是新添加了  leaseTime  属性字段,主要是

    2024年02月16日
    浏览(33)
  • 【Redisson】分布式锁源码分析如何实现多个应用实例互斥

    lockName就是保存到Redis里面的key 直接进行构建方法里面的 super(commandExecutor, name); org.redisson.connection.ServiceManager : private final String id = UUID.randomUUID().toString(); 这个 id 就是 UUID : this.id = getServiceManager().getId(); 这个entryName通过UUID可以区分是哪个应用实例 entryName+threadId可以区分哪个应

    2024年02月11日
    浏览(41)
  • spring boot 实现Redisson分布式锁及其读写锁

    分布式锁,就是控制分布式系统中不同进程共同访问同一共享资源的一种锁的实现。 1、引入依赖 2、配置文件 3、配置类 4、测试代码 5、理解 一、时间设置 默认 lock() 小结 lock.lock (); (1)默认指定锁时间为30s(看门狗时间) (2)锁的自动续期:若是业务超长,运行期间自

    2024年02月12日
    浏览(38)
  • redis实战-redis实现分布式锁&redisson快速入门

    前言 集群环境下的并发问题  分布式锁 定义 需要满足的条件 常见的分布式锁 redis实现分布式锁 核心思路 代码实现 误删情况 逻辑说明 解决方案 代码实现 更为极端的误删情况 Lua脚本解决原子性问题 分布式锁-redission redisson的概念 快速入门 总结 在前面我们已经实现了单机

    2024年02月09日
    浏览(52)
  • 从原理到实践,分析 Redisson 分布式锁的实现方案(二)

            上篇讲解了如何用 Redis 实现分布式锁的方案,它提供了简单的原语来实现基于Redis的分布式锁。然而,Redis作为分布式锁的实现方式也存在一些缺点。本文将引入Redisson来实现分布式锁。         Redisson是一个基于Redis的分布式Java框架。它提供了丰富的功能和工

    2024年02月15日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包