• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

SpringBoot整合分布式锁redisson

武飞扬头像
梁山教父
帮助1

1、导入maven坐标

  1.  
    <!-- 原生,本章使用-->
  2.  
    <dependency>
  3.  
    <groupId>org.redisson</groupId>
  4.  
    <artifactId>redisson</artifactId>
  5.  
    <version>3.13.6</version>
  6.  
    </dependency>
  7.  
     
  8.  
    <!-- 另一种Spring集成starter,本章未使用 -->
  9.  
    <dependency>
  10.  
    <groupId>org.redisson</groupId>
  11.  
    <artifactId>redisson-spring-boot-starter</artifactId>
  12.  
    <version>3.13.6</version>
  13.  
    </dependency>

2、redisson配置类(如果redis没有密码就不需要private String password)

  1.  
    package com.xuechengpluscommon.config;
  2.  
     
  3.  
    import org.redisson.Redisson;
  4.  
    import org.redisson.api.RedissonClient;
  5.  
    import org.redisson.config.Config;
  6.  
    import org.redisson.config.SingleServerConfig;
  7.  
    import org.springframework.beans.factory.annotation.Value;
  8.  
    import org.springframework.context.annotation.Bean;
  9.  
    import org.springframework.context.annotation.Configuration;
  10.  
     
  11.  
    /**
  12.  
    * @description Redisson 配置类
  13.  
    */
  14.  
    @Configuration
  15.  
    public class MyRedissonConfig {
  16.  
     
  17.  
    @Value(value = "${spring.redis.host}")
  18.  
    private String host;
  19.  
    @Value(value = "${spring.redis.port}")
  20.  
    private int port;
  21.  
    @Value(value = "${spring.redis.database}")
  22.  
    private int database;
  23.  
    // @Value(value = "${spring.redis.password}")
  24.  
    // private String password;
  25.  
     
  26.  
    /**
  27.  
    * 单Redis节点模式配置方法
  28.  
    * 其他配置參數,看:
  29.  
    * <a href = "https://github.com/redisson/redisson/wiki/2.-配置方法">
  30.  
    * 单Redis节点模式配置方法
  31.  
    * </a>
  32.  
    *
  33.  
    * @return {@link RedissonClient}
  34.  
    */
  35.  
    @Bean(destroyMethod = "shutdown")
  36.  
    RedissonClient redisson() {
  37.  
    Config config = new Config();
  38.  
    //Redis多节点
  39.  
    // config.useClusterServers()
  40.  
    // .addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:7001");
  41.  
    //Redis单节点
  42.  
    SingleServerConfig singleServerConfig = config.useSingleServer();
  43.  
    //可以用"rediss://"来启用SSL连接
  44.  
    String address = "redis://" host ":" port;
  45.  
    singleServerConfig.setAddress(address);
  46.  
    //设置 数据库编号
  47.  
    singleServerConfig.setDatabase(database);
  48.  
    // singleServerConfig.setPassword(password);
  49.  
    //连接池大小:默认值:64
  50.  
    // singleServerConfig.setConnectionPoolSize()
  51.  
    return Redisson.create(config);
  52.  
    }
  53.  
     
  54.  
    }
学新通

yml中redis的配置

  1.  
    redis:
  2.  
    database: 0
  3.  
    host: ip地址
  4.  
    port: 6379

3、创建redisson的bean

  1.  
    @Autowired
  2.  
    private RedissonClient redisson;

4、测试,入队

  1.  
    @Test
  2.  
    void contextLoads1() {
  3.  
    RQueue<String> queue = redisson.getQueue("RedissonQueue");
  4.  
    queue.add("hello");
  5.  
    System.out.println(queue);
  6.  
    }

redis数据

学新通

5、测试,出队

  1.  
    @Test
  2.  
    void contextLoads2() {
  3.  
    RQueue<String> queue = redisson.getQueue("RedissonQueue");
  4.  
    String remove = queue.remove();
  5.  
    System.out.println(remove);
  6.  
    }

出队数据:

学新通

6、分布式锁

  1.  
    public R redisTest1() throws InterruptedException {
  2.  
    //首先从redis查询数据
  3.  
    Orders redisOrder;
  4.  
    redisOrder=(Orders) redisTemplate.opsForValue().get("redisTest");
  5.  
    //如果存在redis则返回
  6.  
    if(ObjectUtils.isNotEmpty(redisOrder)){
  7.  
    return R.ok(redisOrder);
  8.  
    //如果不存在则从数据库查询
  9.  
    }else {
  10.  
    //首先获取分布式锁
  11.  
    RLock lock = redissonClient.getLock("redisTestDogWatch");
  12.  
    //上锁
  13.  
    lock.lock();
  14.  
     
  15.  
    //获取锁之后进行查询
  16.  
    try {
  17.  
    redisOrder = (Orders) redisTemplate.opsForValue().get("redisTest");
  18.  
    if (ObjectUtils.isNotEmpty(redisOrder)) {
  19.  
    return R.ok(redisOrder);
  20.  
    }
  21.  
    //数据库查询
  22.  
    redisOrder= ordersService.getById(1577177773194113014L);
  23.  
    redisTemplate.opsForValue().set("redisTest", redisOrder );
  24.  
    System.out.println("[从数据库中查询]");
  25.  
     
  26.  
    } catch (Exception e) {
  27.  
    e.printStackTrace();
  28.  
    } finally {
  29.  
    //删除锁
  30.  
    lock.unlock();
  31.  
    }
  32.  
    return R.ok(redisOrder);
  33.  
    }
  34.  
    }
学新通

在这里让线程睡眠35秒

  1.  
    //上锁
  2.  
    lock.lock();
  3.  
    Thread.sleep(35000);

此时三个服务器运行

学新通

测试结果

可以首先看到已经上锁的redisTestDogWatch,每个锁30秒,如果线程未完成则会自动续30秒,如果线程完成到finally中的unlock就删除锁

学新通

目前可以看到只有一个服务器获取到锁

学新通

存储redis的数据

学新通

此时进行并发测试

学新通

依旧保持35秒的睡眠时间

此时可以看到未拿到锁的线程报错

java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: d904f2b9-e75d-472d-a5a6-d0a8cc603a80 thread-id: 210

尝试解锁锁定,未被当前线程锁定 按节点 ID:C731FAC4-9BF7-4F4A-ACC1-A2CC9B78A02F 线程 ID:232

这是因为锁住了,所以无法获取锁,然后看门狗会不断刷新

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfiehjg
系列文章
更多 icon
同类精品
更多 icon
继续加载