Springboot实现分布式锁(Spring Integration+Redis)

一.在项目的pom.xml中添加相关依赖

1)Spring Integration依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-integration</artifactId>
  4. </dependency>

2)Spring Integration Redis依赖

  1. <dependency>
      <groupId>org.springframework.integration</groupId>
      <artifactId>spring-integration-redis</artifactId>
    </dependency>

3)Spring Data Redis依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>

application.yml添加配置

  1. spring:
  2. redis:
  3. port: 6379
  4. host: ***.***.***.***
  5. password: 123456

RedisLockRegistry的配置

  1. package com.lzx.demo.configuration;
  2.  
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.data.redis.connection.RedisConnectionFactory;
  6. import org.springframework.integration.redis.util.RedisLockRegistry;
  7.  
  8. /**
  9. * 描述:锁配置
  10. *
  11. * @Auther: lzx
  12. * @Date: 2019/6/17 15:06
  13. */
  14. @Configuration
  15. public class RedisLockConfiguration {
  16.  
  17. @Bean
  18. public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory){
  19. return new RedisLockRegistry(redisConnectionFactory,"spring-cloud");
  20. }
  21.  
  22. }

二.使用分布式锁

1)自定义分布式锁的注解RedisLock

  1. /**
  2. * 用于标记redis锁
  3. */
  4. @Target(ElementType.METHOD)
  5. @Retention(RetentionPolicy.RUNTIME)
  6. @Documented
  7. public @interface RedisLock {
  8.  
  9. /**
  10. * 可使用SpEL传方法参数
  11. * @return
  12. */
  13. String value() default "";
  14.  
  15. /**
  16. * redis锁的key值
  17. * @return
  18. */
  19. String lockKey() default "";
  20. }

2)使用aop实现锁的获取和释放(切面中的具体逻辑根据实际情况来写)

  1. package com.apps.lock;
  2.  
  3. import com.apps.bcodemsg.MsgResponse;import com.apps.redis.util.SerializeUtil;
  4. import org.apache.commons.lang.StringUtils;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.aspectj.lang.reflect.MethodSignature;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.integration.redis.util.RedisLockRegistry;
  13. import org.springframework.stereotype.Component;
  14.  
  15. import java.lang.reflect.Field;
  16. import java.lang.reflect.Method;
  17. import java.util.concurrent.TimeUnit;
  18. import java.util.concurrent.locks.Lock;
  19.  
  20. /**
  21. * redis分布式锁的切面
  22. */
  23. @Aspect
  24. @Component
  25. public class RedisLockAspect {
  26.  
  27. @Autowired
  28. private RedisLockRegistry redisLockRegistry;
  29.  
  30. @Around(value = "@annotation(redisLock)")
  31. public synchronized Object redisLock(ProceedingJoinPoint joinPoint,
  32. RedisLock redisLock) {
  33. Logger mLog = LoggerFactory.getLogger(SerializeUtil.class);
  34. Object output = null;
  35. try {
  36.  
  37. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  38. Method method = signature.getMethod();
  39. Object[] arguments = joinPoint.getArgs();
  40. Field[] field = arguments[0].getClass().getDeclaredFields();
  41. String value = "";
  42. for (int j = 0; j < field.length; j++) {
  43.  
  44. boolean fieldHasAnno = field[j].isAnnotationPresent(RedisLockKey.class);
  45. if (fieldHasAnno) {
  46. RedisLockKey fieldAnno = field[j].getAnnotation(RedisLockKey.class);
  47. //输出注解属性
  48. String age = fieldAnno.value();
  49. String name = field[j].getName();
  50. name = name.substring(0, 1).toUpperCase() + name.substring(1);
  51. Method m = arguments[0].getClass().getMethod("get" + name);
  52. value = (String) m.invoke(arguments[0]);
  53. System.out.println(value);
  54. }
  55. }
  56. // 获取锁的key
  57. Object lockKey = value;
  58. if (lockKey == null || StringUtils.isBlank((String) lockKey)) {
  59. lockKey = "publistLock";
  60. }
  61. Lock lock = redisLockRegistry.obtain(lockKey);
  62.  
  63. try {
  64. boolean ifLock = lock.tryLock(3, TimeUnit.SECONDS);
  65. // mLog.info("线程[{}]是否获取到了锁:{ }", Thread.currentThread().getName(), ifLock);
  66. /*
  67. * 可以获取到锁,说明当前没有线程在执行该方法
  68. */
  69. if (ifLock) {
  70. output = joinPoint.proceed();
  71. } else {
  72. MsgResponse msgResponse = new MsgResponse();
  73. msgResponse.setCode(400);
  74. msgResponse.setMsg("服务异常!!!");
  75. // mLog.info("线程[{}]未获取到锁,目前锁详情信息为:{}", Thread.currentThread().getName(), lock);
  76. return msgResponse;
  77. }
  78. } catch (Exception e) {
  79. // mLog.error("执行核心奖励扫描时出错:{}", e.getMessage());
  80. } finally {
  81. // mLog.info("尝试解锁[{}]", lockKey);
  82. try {
  83. lock.unlock();
  84. // mLog.info("[{}]解锁成功", lockKey);
  85. } catch (Exception e) {
  86. // mLog.error("解锁dealAction出错:{}", e.getMessage());
  87. }
  88. }
  89. } catch (Throwable e) {
  90. mLog.error("aop redis distributed lock error:{}", e.getLocalizedMessage());
  91. }
  92. return output;
  93. }
  94.  
  95. }

3)使用RedisLock注解实现分布式锁

  1. @LzxLockDistributed(value = "redisLockRegistry",time = 60)
  2. public String redisLockTest() throws InterruptedException {
  3. if(inventory >= 5){
  4. return "已经抢购完了~~~";
  5. }
  6. String s = strArr[inventory];
  7. Thread.sleep(10*1000);
  8. inventory++;
  9. return s;
  10.  
  11. }

本文部分转载自:

https://blog.csdn.net/github_35976996/article/details/93909359

springboot实现分布式锁(spring integration,redis)的更多相关文章

  1. redis分布式锁-spring boot aop+自定义注解实现分布式锁

    接这这一篇redis分布式锁-java实现末尾,实现aop+自定义注解 实现分布式锁 1.为什么需要 声明式的分布式锁 编程式分布式锁每次实现都要单独实现,但业务量大功能复杂时,使用编程式分布式锁无疑 ...

  2. Springboot分布式锁实践(redis)

    springboot2本地锁实践一文中提到用Guava Cache实现锁机制,但在集群中就行不通了,所以我们还一般要借助类似Redis.ZooKeeper 之类的中间件实现分布式锁,下面我们将利用自定 ...

  3. 分布式锁的实现(redis)

    1.单机锁 考虑在并发场景并且存在竞态的状况下,我们就要实现同步机制了,最简单的同步机制就是加锁. 加锁可以帮我们锁住资源,如内存中的变量,或者锁住临界区(线程中的一段代码),使得同一个时刻只有一个线 ...

  4. 基于zookeeper实现分布式锁和基于redis实现分布所的区别

    1,实现方式不同 zookeeper实现分布式锁:通过创建一个临时节点,创建的成功节点的服务则抢占到分布式锁,可做业务逻辑.当业务逻辑完成,连接中断,节点消失,继续下一轮的锁的抢占. redis实现分 ...

  5. SpringBoot进阶教程(二十七)整合Redis之分布式锁

    在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...

  6. SpringBoot集成Redis 一 分布式锁 与 缓存

    1.添加依赖及配置(application.yml) <!-- 引入redis依赖 --> <dependency> <groupId>org.springfram ...

  7. 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  8. 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  9. Redis整合Spring实现分布式锁

    spring把专门的数据操作独立封装在spring-data系列中,spring-data-redis是对Redis的封装 <dependencies> <!-- 添加spring- ...

随机推荐

  1. 制作四个选项卡页 Tab,用户可以通过切换不同的 Tab 页查看不同类别的新闻信息,每个 Tab 有对应的内容版块,点击某个选项卡时,显示对应的内容版块,隐藏其他内容版块,并且为了突出当前的选项卡,还

    查看本章节 查看作业目录 需求说明: 制作四个选项卡页 Tab,用户可以通过切换不同的 Tab 页查看不同类别的新闻信息,每个 Tab 有对应的内容版块,点击某个选项卡时,显示对应的内容版块,隐藏其他 ...

  2. 「影院售票系统」 · Java Swing + MySQL JDBC开发

    目录 文档说明: 一.语言和环境 二.实现功能 三.数据库设计 四.具体要求及推荐实现步骤 五.注意事项 六.评分标准 实现代码: 一.数据库: 二.Java Swing: com.ynavc.Bea ...

  3. nginx rewrite 基础

    一.跳转到首页  如果请求的页面不存在的话就跳转到首页 location / {      if (!-e $request_filename){        rewrite ^/(.*) /ind ...

  4. 初识python 之 MongoDB 基本操作

    MongoDB与SQL对比: MongoDB 三元素:数据库.集合.文档 MongoDB 基本操作命令: db 查看当前数据库 show dbs 查看所有数据库 use 数据库名 切换数据库,如果数据 ...

  5. nginx 超时时间配置说明

    做excel文件导入时 报 504 错误 是nginx网关超时导致 下面几个参数貌似没效果,反正我配置不起作用 这是有问题的配置属性 ,注意   于是我换了配置 ,放在http块里 ,配置生效了 #读 ...

  6. slf4j+logback日志框架 的具体使用操作【spring boot自带的默认日志框架】

    1.前言 是不是还在使用System.out.println()打印数据到控制台看? 东西少还好,如果多起来,那就看的很烦人了,特别还有加时间等信息. 怎么解决? 可以使用日志框架 ,常见的有 log ...

  7. Vue系列教程(一)之初识Vue

    一.Vue和MVVM Vue是一个渐进式的js框架,只注重视图层,结合了HTML+CSS+JS,非常的易用,并且有很好的生态系统,而且vue体积很小,速度很快,优化很到位. Vue技术周四MVVM开发 ...

  8. Cache一致性协议与伪共享问题

    Cache一致性协议 在说伪共享问题之前,有必要聊一聊什么是Cache一致性协议 局部性原理 时间局部性:如果一个信息项正在被访问,那么在近期它很可能还会被再次访问 比如循环.方法的反复调用等 空间局 ...

  9. 从内存管理原理,窥探OS内存管理机制

    摘要:本文将从最简单的内存管理原理说起,带大家一起窥探OS的内存管理机制,由此熟悉底层的内存管理机制,写出高效的应用程序. 本文分享自华为云社区<探索OS的内存管理原理>,作者:元闰子 . ...

  10. 【Java常用类】两个Date类

    两个Date类 java.util.Date类 两个构造器的使用 构造器一:Date():创建一个对应当前时间的Date对象 构造器二:创建指定毫秒数的Date对象 两个方法的使用 toString( ...