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- ...
随机推荐
- 使用PyTorch构建神经网络模型进行手写识别
使用PyTorch构建神经网络模型进行手写识别 PyTorch是一种基于Torch库的开源机器学习库,应用于计算机视觉和自然语言处理等应用,本章内容将从安装以及通过Torch构建基础的神经网络,计算梯 ...
- 【jvm】09-full gc分析思路
[jvm]09-full gc分析思路 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点个赞. ...
- 论文翻译:2020_Acoustic Echo Cancellation Based on Recurrent Neural Network
论文地址:https://ieeexplore.ieee.org/abstract/document/9306224 基于RNN的回声消除 摘要 本文提出了一种基于深度学习的语音分离技术的回声消除方法 ...
- python 自动化测试框架unittest与pytest的区别
前言: 有使用过unittest单元测试框架,再使用pytest单元测试框架,就可以明显感觉到pytest比unittest真的简洁.方便很多. unittest与pytest的区别: 主要从用例编写 ...
- Numpy实现简单BP神经网络识别手写数字
本文将用Numpy实现简单BP神经网络完成对手写数字图片的识别,数据集为42000张带标签的28x28像素手写数字图像.在计算机完成对手写数字图片的识别过程中,代表图片的28x28=764个像素的特征 ...
- 打开Cmd的方式与基础Dos命令
基础的Dos命令 打开Cmd的方式 开始->Windows系统->命令提示符 Win键 + R输入cmd打开控制台 在任意的文件夹下面,按住shift键+鼠标右键点击在此处打开powers ...
- Selenium2+python自动化65-js定位几种方法总结
Selenium2+python自动化65-js定位几种方法总结 前言 本篇总结了几种js常用的定位元素方法,并用js点击按钮,对input输入框输入文本 一.以下总结了5种js定位的方法 除了i ...
- 微服务架构 | 3.3 Apache Zookeeper 注册中心
@ 目录 前言 1. Zookeeper 基础知识 1.1 Zookeeper 是什么 1.2 Zookeeper 的数据结构 1.3 Watcher 机制 1.4 常见应用场景分析 1.5 Zook ...
- manjaro20WPS缺少字体
宋体等 sudo pacman -S ttf-wps-fonts Ariel和Times New Roman https://askubuntu.com/questions/651441/how-to ...
- manjora20安装搜狗输入法
先安装好fcitx和yay yay -S fcitx-sogoupinyin sudo pacman -S base-devel 这是因为需要使用外网,需要配置代理. 注意 manjora20输入法一 ...