springboot实现分布式锁(spring integration,redis)
Springboot实现分布式锁(Spring Integration+Redis)
一.在项目的pom.xml中添加相关依赖
1)Spring Integration依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-integration</artifactId>
- </dependency>
2)Spring Integration Redis依赖
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
3)Spring Data Redis依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
application.yml添加配置
- spring:
- redis:
- port: 6379
- host: ***.***.***.***
- password: 123456
RedisLockRegistry的配置
- package com.lzx.demo.configuration;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.integration.redis.util.RedisLockRegistry;
- /**
- * 描述:锁配置
- *
- * @Auther: lzx
- * @Date: 2019/6/17 15:06
- */
- @Configuration
- public class RedisLockConfiguration {
- @Bean
- public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory){
- return new RedisLockRegistry(redisConnectionFactory,"spring-cloud");
- }
- }
二.使用分布式锁
1)自定义分布式锁的注解RedisLock
- /**
- * 用于标记redis锁
- */
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface RedisLock {
- /**
- * 可使用SpEL传方法参数
- * @return
- */
- String value() default "";
- /**
- * redis锁的key值
- * @return
- */
- String lockKey() default "";
- }
2)使用aop实现锁的获取和释放(切面中的具体逻辑根据实际情况来写)
- package com.apps.lock;
- import com.apps.bcodemsg.MsgResponse;import com.apps.redis.util.SerializeUtil;
- import org.apache.commons.lang.StringUtils;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.integration.redis.util.RedisLockRegistry;
- import org.springframework.stereotype.Component;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.locks.Lock;
- /**
- * redis分布式锁的切面
- */
- @Aspect
- @Component
- public class RedisLockAspect {
- @Autowired
- private RedisLockRegistry redisLockRegistry;
- @Around(value = "@annotation(redisLock)")
- public synchronized Object redisLock(ProceedingJoinPoint joinPoint,
- RedisLock redisLock) {
- Logger mLog = LoggerFactory.getLogger(SerializeUtil.class);
- Object output = null;
- try {
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- Method method = signature.getMethod();
- Object[] arguments = joinPoint.getArgs();
- Field[] field = arguments[0].getClass().getDeclaredFields();
- String value = "";
- for (int j = 0; j < field.length; j++) {
- boolean fieldHasAnno = field[j].isAnnotationPresent(RedisLockKey.class);
- if (fieldHasAnno) {
- RedisLockKey fieldAnno = field[j].getAnnotation(RedisLockKey.class);
- //输出注解属性
- String age = fieldAnno.value();
- String name = field[j].getName();
- name = name.substring(0, 1).toUpperCase() + name.substring(1);
- Method m = arguments[0].getClass().getMethod("get" + name);
- value = (String) m.invoke(arguments[0]);
- System.out.println(value);
- }
- }
- // 获取锁的key
- Object lockKey = value;
- if (lockKey == null || StringUtils.isBlank((String) lockKey)) {
- lockKey = "publistLock";
- }
- Lock lock = redisLockRegistry.obtain(lockKey);
- try {
- boolean ifLock = lock.tryLock(3, TimeUnit.SECONDS);
- // mLog.info("线程[{}]是否获取到了锁:{ }", Thread.currentThread().getName(), ifLock);
- /*
- * 可以获取到锁,说明当前没有线程在执行该方法
- */
- if (ifLock) {
- output = joinPoint.proceed();
- } else {
- MsgResponse msgResponse = new MsgResponse();
- msgResponse.setCode(400);
- msgResponse.setMsg("服务异常!!!");
- // mLog.info("线程[{}]未获取到锁,目前锁详情信息为:{}", Thread.currentThread().getName(), lock);
- return msgResponse;
- }
- } catch (Exception e) {
- // mLog.error("执行核心奖励扫描时出错:{}", e.getMessage());
- } finally {
- // mLog.info("尝试解锁[{}]", lockKey);
- try {
- lock.unlock();
- // mLog.info("[{}]解锁成功", lockKey);
- } catch (Exception e) {
- // mLog.error("解锁dealAction出错:{}", e.getMessage());
- }
- }
- } catch (Throwable e) {
- mLog.error("aop redis distributed lock error:{}", e.getLocalizedMessage());
- }
- return output;
- }
- }
3)使用RedisLock注解实现分布式锁
- @LzxLockDistributed(value = "redisLockRegistry",time = 60)
- public String redisLockTest() throws InterruptedException {
- if(inventory >= 5){
- return "已经抢购完了~~~";
- }
- String s = strArr[inventory];
- Thread.sleep(10*1000);
- inventory++;
- return s;
- }
本文部分转载自:
https://blog.csdn.net/github_35976996/article/details/93909359
springboot实现分布式锁(spring integration,redis)的更多相关文章
- redis分布式锁-spring boot aop+自定义注解实现分布式锁
接这这一篇redis分布式锁-java实现末尾,实现aop+自定义注解 实现分布式锁 1.为什么需要 声明式的分布式锁 编程式分布式锁每次实现都要单独实现,但业务量大功能复杂时,使用编程式分布式锁无疑 ...
- Springboot分布式锁实践(redis)
springboot2本地锁实践一文中提到用Guava Cache实现锁机制,但在集群中就行不通了,所以我们还一般要借助类似Redis.ZooKeeper 之类的中间件实现分布式锁,下面我们将利用自定 ...
- 分布式锁的实现(redis)
1.单机锁 考虑在并发场景并且存在竞态的状况下,我们就要实现同步机制了,最简单的同步机制就是加锁. 加锁可以帮我们锁住资源,如内存中的变量,或者锁住临界区(线程中的一段代码),使得同一个时刻只有一个线 ...
- 基于zookeeper实现分布式锁和基于redis实现分布所的区别
1,实现方式不同 zookeeper实现分布式锁:通过创建一个临时节点,创建的成功节点的服务则抢占到分布式锁,可做业务逻辑.当业务逻辑完成,连接中断,节点消失,继续下一轮的锁的抢占. redis实现分 ...
- SpringBoot进阶教程(二十七)整合Redis之分布式锁
在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...
- SpringBoot集成Redis 一 分布式锁 与 缓存
1.添加依赖及配置(application.yml) <!-- 引入redis依赖 --> <dependency> <groupId>org.springfram ...
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- Redis整合Spring实现分布式锁
spring把专门的数据操作独立封装在spring-data系列中,spring-data-redis是对Redis的封装 <dependencies> <!-- 添加spring- ...
随机推荐
- 制作四个选项卡页 Tab,用户可以通过切换不同的 Tab 页查看不同类别的新闻信息,每个 Tab 有对应的内容版块,点击某个选项卡时,显示对应的内容版块,隐藏其他内容版块,并且为了突出当前的选项卡,还
查看本章节 查看作业目录 需求说明: 制作四个选项卡页 Tab,用户可以通过切换不同的 Tab 页查看不同类别的新闻信息,每个 Tab 有对应的内容版块,点击某个选项卡时,显示对应的内容版块,隐藏其他 ...
- 「影院售票系统」 · Java Swing + MySQL JDBC开发
目录 文档说明: 一.语言和环境 二.实现功能 三.数据库设计 四.具体要求及推荐实现步骤 五.注意事项 六.评分标准 实现代码: 一.数据库: 二.Java Swing: com.ynavc.Bea ...
- nginx rewrite 基础
一.跳转到首页 如果请求的页面不存在的话就跳转到首页 location / { if (!-e $request_filename){ rewrite ^/(.*) /ind ...
- 初识python 之 MongoDB 基本操作
MongoDB与SQL对比: MongoDB 三元素:数据库.集合.文档 MongoDB 基本操作命令: db 查看当前数据库 show dbs 查看所有数据库 use 数据库名 切换数据库,如果数据 ...
- nginx 超时时间配置说明
做excel文件导入时 报 504 错误 是nginx网关超时导致 下面几个参数貌似没效果,反正我配置不起作用 这是有问题的配置属性 ,注意 于是我换了配置 ,放在http块里 ,配置生效了 #读 ...
- slf4j+logback日志框架 的具体使用操作【spring boot自带的默认日志框架】
1.前言 是不是还在使用System.out.println()打印数据到控制台看? 东西少还好,如果多起来,那就看的很烦人了,特别还有加时间等信息. 怎么解决? 可以使用日志框架 ,常见的有 log ...
- Vue系列教程(一)之初识Vue
一.Vue和MVVM Vue是一个渐进式的js框架,只注重视图层,结合了HTML+CSS+JS,非常的易用,并且有很好的生态系统,而且vue体积很小,速度很快,优化很到位. Vue技术周四MVVM开发 ...
- Cache一致性协议与伪共享问题
Cache一致性协议 在说伪共享问题之前,有必要聊一聊什么是Cache一致性协议 局部性原理 时间局部性:如果一个信息项正在被访问,那么在近期它很可能还会被再次访问 比如循环.方法的反复调用等 空间局 ...
- 从内存管理原理,窥探OS内存管理机制
摘要:本文将从最简单的内存管理原理说起,带大家一起窥探OS的内存管理机制,由此熟悉底层的内存管理机制,写出高效的应用程序. 本文分享自华为云社区<探索OS的内存管理原理>,作者:元闰子 . ...
- 【Java常用类】两个Date类
两个Date类 java.util.Date类 两个构造器的使用 构造器一:Date():创建一个对应当前时间的Date对象 构造器二:创建指定毫秒数的Date对象 两个方法的使用 toString( ...