在 Spring Boot 中结合 Redis 实现分布式锁,可以通过 Redisson
或 Jedis
等客户端来操作 Redis,从而实现分布式锁。以下是使用 Redisson 实现分布式锁的示例。
1. 添加依赖
在 pom.xml
中添加 Redisson 依赖:
登录后复制
plain
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.5</version>
</dependency>
2. 配置 Redis
在 application.properties
或 application.yml
中配置 Redis 连接:
application.properties 示例:
登录后复制
plain
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=your-password
spring.redis.timeout=2000
application.yml 示例:
登录后复制
plain
spring:
redis:
host: localhost
port: 6379
password: your-password
timeout: 2000
3. 使用 Redisson 实现分布式锁
创建服务类:
登录后复制
plain
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class RedisLockService {
@Autowired
private RedissonClient redissonClient;
public void lockMethod() {
// 获取分布式锁
RLock lock = redissonClient.getLock("myLock");
try {
// 尝试加锁,等待时间 10 秒,锁定时间 30 秒
if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
// 执行需要加锁的业务代码
System.out.println("Lock acquired, executing critical section");
// 模拟执行业务操作
Thread.sleep(10000);
} else {
System.out.println("Could not acquire lock, try again later");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// 释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
4. 在 Controller 中调用服务
登录后复制
plain
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RedisLockController {
@Autowired
private RedisLockService redisLockService;
@GetMapping("/test-lock")
public String testLock() {
redisLockService.lockMethod();
return "Lock process completed.";
}
}
5. 启动项目并测试
启动 Spring Boot 项目后,访问 http://localhost:8080/test-lock
,你将看到分布式锁成功应用到方法中的效果。
关键点解释
redissonClient.getLock("myLock")
:获取一个名为 "myLock" 的锁。tryLock(10, 30, TimeUnit.SECONDS)
:尝试加锁,最多等待 10 秒,加锁后锁定 30 秒。如果无法获取锁,则会返回false
。lock.unlock()
:在业务代码执行完成后,手动释放锁。
注意事项
- 锁的粒度:需要确保锁的粒度适合业务场景,避免过度加锁导致性能问题。
- 锁的超时:在分布式环境下,为避免死锁,应该设置锁的过期时间,即使业务没有完成也会自动释放锁。
- Redis的高可用性:如果 Redis 服务出现故障,锁也会失效,因此需要考虑 Redis 集群或哨兵机制来保证高可用。
通过这种方式,你可以在 Spring Boot 项目中轻松地实现分布式锁,避免多个实例间的数据冲突。