飞道的博客

SpringBoot整合分布式锁redisson

676人阅读  评论(0)

1、导入maven坐标


   
  1. <!-- 用redisson作为所有分布式锁,分布式对象等功能框架-->
  2. <dependency>
  3. <groupId>org.redisson</groupId>
  4. <artifactId>redisson</artifactId>
  5. <version> 3.12 .5</version>
  6. </dependency>

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


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

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. try {
  16. redisOrder = (Orders) redisTemplate.opsForValue().get( "redisTest");
  17. if (ObjectUtils.isNotEmpty(redisOrder)) {
  18. return R.ok(redisOrder);
  19. }
  20. //数据库查询
  21. redisOrder= ordersService.getById( 1577177773194113014L);
  22. redisTemplate.opsForValue().set( "redisTest", redisOrder );
  23. System.out.println( "[从数据库中查询]");
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. } finally {
  27. //删除锁
  28. lock.unlock();
  29. }
  30. return R.ok(redisOrder);
  31. }
  32. }

在这里让线程睡眠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

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


转载:https://blog.csdn.net/weixin_55127182/article/details/129125249
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场