Redisson 是一个基于 Redis 的 Java 客户端,提供了丰富的分布式锁功能,如红锁(Red Lock)、公平锁、可重入锁等。Redisson 的设计使得开发者可以非常方便地在 Spring Boot 项目中集成这些功能,而不需要深入了解底层的实现细节。
特点
-
支持多种类型的分布式锁。 -
内置了读写锁、信号量等功能。 -
提供了简单的 API 和强大的容错机制。 -
可以通过注解的方式简化锁的使用。
常见应用场景
-
分布式锁:确保多个服务实例不会同时修改共享资源。 -
分布式对象:跨多个 JVM 实例共享数据结构(如列表、集合、队列、地图)。 -
分布式消息队列:构建发布/订阅模式的消息传递系统。 -
分布式任务调度:安排定时任务或一次性任务,并确保同一时间只有一个节点执行特定任务。 -
分布式计数器:统计访问次数、点击量等指标,适用于高并发环境。
代码实操
通过自定义注解和切面(AOP)来简化锁的使用,并确保线程安全。
1. 添加依赖
首先,在 pom.xml
中添加 Redisson 和 Spring Boot Starter 的依赖:
<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>
</dependencies>
2. 配置 Redisson
创建 application.yml
文件配置 Redis 连接信息:
spring:
redis:
host: localhost
port: 6379
password: your_password_if_any
# Redisson configuration
redisson:
single-server-address: redis://@localhost:6379
3. 创建自定义注解和切面
自定义注解
定义一个自定义注解 @DistributedLock
,用于标记需要加锁的方法。
package com.example.demo.lock;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
String lockName();
}
切面类
创建一个切面类 DistributedLockAspect
来处理加锁和解锁逻辑。
package com.example.demo.lock;
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.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
publicclass DistributedLockAspect {
@Autowired
private RedissonClient redissonClient;
@Around("@annotation(com.example.demo.lock.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)) {
thrownew RuntimeException("Failed to acquire lock.");
}
return joinPoint.proceed();
} finally {
// 确保在任何情况下都能释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
4. 创建测试控制器
创建一个简单的控制器 LockController
来测试分布式锁的功能。
package com.example.demo.controller;
import com.example.demo.lock.DistributedLock;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclass LockController {
privateint counter = 0;
@GetMapping("/increment")
@DistributedLock(lockName = "counterLock")
public String incrementCounter() {
counter++;
return"Counter value: " + counter;
}
}
5. 测试结果
为了验证注解式分布式锁的效果,可以通过模拟高并发请求来测试 /increment
接口。可以使用 Apache Bench (ab) 或者其他负载测试工具来发送大量并发请求到该接口。
我们在本地环境中启动了 Spring Boot 应用程序,并且 Redis 服务器也运行正常。然后执行如下命令进行测试:
ab -n 100 -c 10 http://localhost:8080/increment
这条命令表示发送100个请求,每个批次10个并发请求。
-
每次请求都应该成功返回一个新的计数值,没有出现重复值。 -
即使有多个请求几乎同时到达,由于分布式锁的存在,它们会被顺序化执行,保证了线程安全。
总结
基于注解的分布式锁功能,并且通过切面编程(AOP)简化了锁的管理逻辑。这种方法不仅提高了代码的可读性和维护性,还确保了在高并发环境下对共享资源的安全访问。
关注我,送Java福利
/**
* 这段代码只有Java开发者才能看得懂!
* 关注我微信公众号之后,
* 发送:"666",
* 即可获得一本由Java大神一手面试经验诚意出品
* 《Java开发者面试百宝书》Pdf电子书
* 福利截止日期为2025年01月22日止
* 手快有手慢没!!!
*/
System.out.println("请关注我的微信公众号:");
System.out.println("Java知识日历");
原文始发于微信公众号(Java知识日历):SpringBoot与Redisson整合,用注解方式解决分布式锁的使用问题
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/310646.html