下面为你提供一个完整的 spring boot + redisson 分布式锁示例项目结构,包含:
- maven 依赖配置
- redisson 配置类(支持单机/集群)
- 分布式锁工具封装
- 控制器示例(模拟并发场景)
- 测试方法建议
你可以直接复制到你的项目中使用。
📁 项目结构概览
src/
├── main/
│ ├── java/
│ │ └── com.example.redissonlock/
│ │ ├── redissonlockapplication.java
│ │ ├── config/
│ │ │ └── redissonconfig.java
│ │ ├── service/
│ │ │ ├── orderservice.java
│ │ │ └── impl/
│ │ │ └── orderserviceimpl.java
│ │ └── controller/
│ │ └── ordercontroller.java
│ └── resources/
│ ├── application.yml
│ └── application-dev.yml (可选)
└── test/
└── java/
└── com.example.redissonlock/
└── redissonlocktest.java1️⃣ maven 依赖(pom.xml)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>3.2.5</version> <!-- 支持 jdk 17+ -->
<relativepath/>
</parent>
<groupid>com.example</groupid>
<artifactid>redisson-lock-demo</artifactid>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- web -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!-- redisson starter (自动配置 redissonclient) -->
<dependency>
<groupid>org.redisson</groupid>
<artifactid>redisson-spring-boot-starter</artifactid>
<version>3.25.2</version> <!-- 检查最新版:https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
</dependency>
<!-- lombok (可选,简化日志/getter/setter) -->
<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>✅ 注意:
redisson-spring-boot-starter已包含spring-boot-starter-data-redis和redisson核心包。
2️⃣ 配置文件(application.yml)
spring:
application:
name: redisson-lock-demo
# redis 连接配置(单机模式)
redis:
host: localhost
port: 6379
database: 0
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
# redisson 自定义配置(可选,如需调整看门狗等)
# 如果不配置,redisson 会自动使用 spring.redis 下的连接信息🔁 集群模式示例(替换 spring.redis):
spring:
redis:
cluster:
nodes:
- 192.168.1.10:7000
- 192.168.1.10:7001
- 192.168.1.10:7002
password: your_password
timeout: 2000ms3️⃣ redisson 配置类(可选,用于自定义)
⚠️ 如果只用单机 redis,其实不需要写这个类!
redisson-spring-boot-starter会自动创建redissonclient。
但如果你需要自定义(如修改看门狗超时、启用 codec),可以添加:
// src/main/java/com/example/redissonlock/config/redissonconfig.java
package com.example.redissonlock.config;
import org.redisson.redisson;
import org.redisson.api.redissonclient;
import org.redisson.config.config;
import org.springframework.beans.factory.annotation.value;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
@configuration
public class redissonconfig {
@value("${spring.redis.host}")
private string redishost;
@value("${spring.redis.port}")
private int redisport;
@bean(destroymethod = "shutdown")
public redissonclient redissonclient() {
config config = new config();
config.usesingleserver()
.setaddress("redis://" + redishost + ":" + redisport)
.settimeout(3000)
.setconnectionpoolsize(10);
// 可选:调整看门狗超时(默认30秒)
// config.setlockwatchdogtimeout(60000); // 60秒
return redisson.create(config);
}
}4️⃣ 业务服务层(带分布式锁)
// src/main/java/com/example/redissonlock/service/orderservice.java
package com.example.redissonlock.service;
public interface orderservice {
void createorder(string userid, string orderid);
}// src/main/java/com/example/redissonlock/service/impl/orderserviceimpl.java
package com.example.redissonlock.service.impl;
import com.example.redissonlock.service.orderservice;
import lombok.extern.slf4j.slf4j;
import org.redisson.api.rlock;
import org.redisson.api.redissonclient;
import org.springframework.stereotype.service;
import java.util.concurrent.timeunit;
@slf4j
@service
public class orderserviceimpl implements orderservice {
private final redissonclient redissonclient;
public orderserviceimpl(redissonclient redissonclient) {
this.redissonclient = redissonclient;
}
@override
public void createorder(string userid, string orderid) {
// 锁 key 建议包含业务唯一标识,避免全局锁
string lockkey = "order:create:" + orderid;
rlock lock = redissonclient.getlock(lockkey);
try {
// 尝试加锁:最多等待 3 秒,持有锁 30 秒(看门狗会自动续期)
boolean islocked = lock.trylock(3, 30, timeunit.seconds);
if (!islocked) {
log.warn("获取分布式锁失败,orderid={}", orderid);
throw new runtimeexception("系统繁忙,请稍后再试");
}
log.info("线程 {} 获取锁成功,开始处理订单 {}", thread.currentthread().getname(), orderid);
// 模拟业务耗时(即使超过30秒也不会丢锁!)
thread.sleep(5000);
// todo: 真实业务逻辑(如扣库存、写db)
log.info("订单 {} 创建成功", orderid);
} catch (interruptedexception e) {
thread.currentthread().interrupt();
log.error("订单处理被中断", e);
throw new runtimeexception(e);
} finally {
// 安全释放锁(redisson 会校验线程id)
if (lock.isheldbycurrentthread()) {
lock.unlock();
log.info("线程 {} 释放锁,orderid={}", thread.currentthread().getname(), orderid);
}
}
}
}5️⃣ 控制器(用于测试)
// src/main/java/com/example/redissonlock/controller/ordercontroller.java
package com.example.redissonlock.controller;
import com.example.redissonlock.service.orderservice;
import lombok.requiredargsconstructor;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
@requiredargsconstructor
public class ordercontroller {
private final orderservice orderservice;
@getmapping("/create-order")
public string createorder(@requestparam string userid,
@requestparam string orderid) {
orderservice.createorder(userid, orderid);
return "order created: " + orderid;
}
}6️⃣ 启动类
// src/main/java/com/example/redissonlock/redissonlockapplication.java
package com.example.redissonlock;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
@springbootapplication
public class redissonlockapplication {
public static void main(string[] args) {
springapplication.run(redissonlockapplication.class, args);
}
}🧪 如何测试并发效果?
方法 1:使用 jmeter / postman runner
- 发起多个并发请求到:
get http://localhost:8080/create-order?userid=u1&orderid=o1001 - 观察日志:同一 orderid 的请求会串行执行
方法 2:单元测试(模拟多线程)
// src/test/java/com/example/redissonlock/redissonlocktest.java
@test
void testconcurrentordercreation() throws interruptedexception {
executorservice executor = executors.newfixedthreadpool(5);
countdownlatch latch = new countdownlatch(5);
for (int i = 0; i < 5; i++) {
executor.submit(() -> {
try {
orderservice.createorder("u1", "o1001"); // 相同 orderid
} finally {
latch.countdown();
}
});
}
latch.await(); // 等待所有线程完成
executor.shutdown();
}✅ 关键优势总结
| 特性 | 说明 |
|---|---|
| 自动续期 | watchdog 默认每 10s 续期一次,不怕业务超时 |
| 安全释放 | 基于线程 id 校验,不会误删其他线程的锁 |
| 可重入 | 同一线程可多次加锁 |
| 无死锁风险 | 即使应用 crash,锁也会在 watchdog 超时后释放 |
| spring boot 集成简单 | starter 自动配置,开箱即用 |
📌 注意事项
- 锁 key 设计:务必带上业务唯一标识(如
order:{orderid}),避免锁粒度太大。 - 不要在锁内做远程调用:如 http 请求、mq 发送,可能因网络延迟导致锁持有时间过长。
- 监控锁状态:可通过 redis cli 查看:
keys *order*、ttl your_lock_key - 生产环境 redis 高可用:建议使用 redis cluster 或 sentinel。
到此这篇关于完整的 spring boot + redisson 分布式锁示例的文章就介绍到这了,更多相关spring boot redisson 分布式锁内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论