欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > SpringBoot与Redisson整合,用注解方式解决分布式锁的使用问题

SpringBoot与Redisson整合,用注解方式解决分布式锁的使用问题

2025/3/26 21:15:40 来源:https://blog.csdn.net/qq_42236791/article/details/146407105  浏览:    关键词:SpringBoot与Redisson整合,用注解方式解决分布式锁的使用问题

文章引用:https://mp.weixin.qq.com/s/XgdKE2rBKL0-nFk2NJPuyg

一、单个服务

1.代码

该接口的作用是累加一个值,访问一次该值加1

@RestController
public class LockController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/increment")public String increment() {int counter = Integer.parseInt(stringRedisTemplate.opsForValue().get("count"));counter++;System.out.println("当前结果:" + counter);stringRedisTemplate.opsForValue().set("count", String.valueOf(counter));return "结果:" + counter;}
}

2.jmeter工具压测

用100个线程,每个线程访问100次去压测,理论上该值最后应该返回10000
在这里插入图片描述

3.结果

在这里插入图片描述
在这里插入图片描述

发生了线程安全问题,部分请求返回结果相同

4.解决办法:加锁

@RestController
public class LockController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/increment")public synchronized String increment() {int counter = Integer.parseInt(stringRedisTemplate.opsForValue().get("count"));counter++;System.out.println("当前结果:" + counter);stringRedisTemplate.opsForValue().set("count", String.valueOf(counter));return "结果:" + counter;}
}

在这里插入图片描述
在非集群模式下,简单上锁能解决线程安全问题。

二、集群模式

代码相同,idea启动两个相同的服务

1.启动两个服务

在这里插入图片描述

2.nginx配置负载均衡

upstream backend {# 定义后端服务器列表server localhost:8081;server localhost:8082;}server {listen 8080;location / {# 将请求代理到后端服务器proxy_pass http://backend;}}

3.jmeter工具压测

用100个线程,每个线程访问100次去压测,理论上该值最后应该返回10000
在这里插入图片描述
在这里插入图片描述
还是出了线程安全问题,synchronized只能锁住单个服务

三、SpringBoot整合Redisson(注解方式)

1.依赖和配置文件

<dependencies><!-- Spring Boot Starter for Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--         Redisson Dependency--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.17.6</version><!-- 请根据需要调整版本 --></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.10</version></dependency></dependencies>
spring:
redis:host:localhostport:6379# Redisson configuration
redisson:single-server-address:redis://@localhost:6379

2.代码

注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {String lockName();
}

切面

@Aspect
@Component
public class DistributedLockAspect {@Autowiredprivate RedissonClient redissonClient;@Around("@annotation(DistributedLock)")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();DistributedLock annotation = signature.getMethod().getAnnotation(DistributedLock.class);String lockName = annotation.lockName();RLock lock = redissonClient.getLock(lockName);try {// 尝试获取锁,最多等待10秒,持有锁的时间为30秒if (!lock.tryLock(10, 30, TimeUnit.SECONDS)) {throw new RuntimeException("Failed to acquire lock.");}return joinPoint.proceed();} finally {// 确保在任何情况下都能释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();}}}
}

接口

@RestController
public class LockController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/increment")@DistributedLock(lockName = "counterLock")public String increment() {int counter = Integer.parseInt(stringRedisTemplate.opsForValue().get("count"));counter++;System.out.println("当前结果:" + counter);stringRedisTemplate.opsForValue().set("count", String.valueOf(counter));return "结果:" + counter;}
}

3.结果

实现了分布式锁,俩个服务依次接受了所有请求,并无重复值
在这里插入图片描述
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词