Docker实现容器化的分布式锁服务RedisLock的快速搭建
作者:冷炫風刃
本文主要介绍了Docker实现容器化的分布式锁服务RedisLock的快速搭建,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
基于搜索结果,我为你梳理了 Docker 快速搭建 Redis 分布式锁服务的完整方案。核心思路是:先通过 Docker 部署 Redis 实例,再通过成熟的客户端库(如 Java 的 Redisson、Go 的 redislock)实现分布式锁逻辑,避免从零造轮子。
一、方案选型对比
| 方案 | 复杂度 | 可靠性 | 适用场景 |
|---|---|---|---|
| SET NX + Lua 手动实现 | 高 | 中 | 学习原理,不推荐生产 |
| Redisson (Java) | 低 | 高 | Java 生态,生产首选 |
| redislock (Go) | 低 | 高 | Go 生态,轻量易用 |
| Redlock 算法 | 中 | 极高 | 多主节点高可用场景 |
生产环境强烈推荐 Redisson 或 redislock,它们内置了看门狗自动续期、可重入锁等机制。
二、Docker 快速部署 Redis
1. 单节点快速启动(开发测试)
# 拉取官方镜像 docker pull redis:7.2 # 运行容器(带密码认证,持久化目录挂载) docker run -d \ --name redis-lock \ -p 6379:6379 \ -v /data/redis:/data \ redis:7.2 \ redis-server --requirepass yourpassword --appendonly yes
2. Docker Compose 部署(推荐,含生产级配置)
创建 docker-compose.yml:
services:
redis:
container_name: redis-lock-server
image: redis:7.2
restart: always
ulimits:
nofile:
soft: 65536
hard: 65536
sysctls:
- net.core.somaxconn=511
environment:
- TZ=Asia/Shanghai
networks:
- lock-net
ports:
- "6379:6379"
volumes:
- ./data:/data
- ./config/redis.conf:/usr/local/etc/redis/redis.conf:ro
command: redis-server /usr/local/etc/redis/redis.conf
networks:
lock-net:
driver: bridge创建 config/redis.conf:
# 基础配置 port 6379 bind 0.0.0.0 daemonize no dir /data # 安全认证(分布式锁必须设置,防止未授权释放) requirepass yourpassword # 持久化(AOF + RDB 双保险) appendonly yes appendfsync everysec save 900 1 save 300 10 save 60 10000 # 内存与性能 maxmemory 256mb maxmemory-policy noeviction
启动:
mkdir -p data config docker compose up -d
三、客户端实现分布式锁
方案 A:Java + Redisson(生产级)
Maven 依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.27.0</version>
</dependency>配置类:
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("yourpassword")
.setConnectionMinimumIdleSize(10);
return Redisson.create(config);
}
}业务使用:
@Service
public class OrderService {
@Autowired
private RedissonClient redissonClient;
public void deductStock(Long productId) {
// 锁命名规范:业务:资源:ID
RLock lock = redissonClient.getLock("lock:stock:" + productId);
try {
// 尝试加锁,最多等待3秒,锁10秒后自动释放
// 不指定leaseTime时,Redisson 看门狗会自动续期(默认30秒检查一次)
boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
if (!locked) {
throw new RuntimeException("获取锁失败,请重试");
}
// 执行业务逻辑...
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// 必须判断当前线程是否持有锁,避免误释放
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}Redisson 核心优势:
- 看门狗机制:业务未执行完时自动续期,防止锁提前释放
- 可重入锁:同一线程可多次获取同一锁
- Lua 原子操作:加锁/解锁均为原子性,避免竞态条件
方案 B:Go + redislock(轻量级)
package main
import (
"context"
"fmt"
"time"
"github.com/bsm/redislock"
"github.com/redis/go-redis/v9"
)
func main() {
// 连接 Redis
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "yourpassword",
DB: 0,
})
// 创建锁管理器
locker := redislock.New(client)
ctx := context.Background()
// 获取锁(TTL 10秒,重试策略)
lock, err := locker.Obtain(ctx, "my-lock", 10*time.Second, &redislock.Options{
RetryStrategy: redislock.LinearBackoff(100 * time.Millisecond),
})
if err == redislock.ErrNotObtained {
fmt.Println("锁已被占用")
return
} else if err != nil {
panic(err)
}
// 必须释放锁
defer lock.Release(ctx)
fmt.Println("获取锁成功,执行业务...")
time.Sleep(5 * time.Second)
}四、高可用进阶:Redlock 多主部署
当单节点 Redis 存在单点故障风险时,可采用 Redis 官方推荐的 Redlock 算法:
Docker Compose 部署 3 主节点
services:
redis-master-1:
image: redis:7.2
container_name: redlock-1
ports: ["6381:6379"]
command: redis-server --port 6379 --appendonly yes
redis-master-2:
image: redis:7.2
container_name: redlock-2
ports: ["6382:6379"]
command: redis-server --port 6379 --appendonly yes
redis-master-3:
image: redis:7.2
container_name: redlock-3
ports: ["6383:6379"]
command: redis-server --port 6379 --appendonly yesRedisson Redlock 配置
Config config = new Config();
config.useRedLock()
.addSlaveAddress("redis://localhost:6381", "redis://localhost:6382", "redis://localhost:6383");
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getRedLock("myLock"); // 红锁Redlock 核心逻辑:
- 记录起始时间 T1
- 向 N 个独立主节点顺序申请锁,每个节点设置短超时(如 50ms)
- 计算获取耗时
T2 - T1 - 仅在 大多数节点(N/2+1)加锁成功 且 总耗时 < 锁有效期 时才算成功
- 失败时向所有节点发送解锁指令
五、关键避坑指南
| 坑点 | 正确做法 |
|---|---|
| SETNX + EXPIRE 分步执行 | 使用 SET key value NX PX 30000 原子命令 |
| 锁到期但业务未完成 | 使用 Redisson 看门狗自动续期,或合理评估业务耗时设置 TTL |
| A 客户端释放 B 客户端的锁 | 锁 value 使用唯一随机值(UUID+线程ID),释放前 Lua 校验 |
| 集群主从切换导致锁丢失 | 生产环境使用 Redlock 或多主节点部署 |
| 未处理锁续期失败 | 捕获异常,设置业务最大执行时间兜底 |
六、快速验证脚本
启动后验证 Redis 与锁功能:
# 进入容器
docker exec -it redis-lock-server redis-cli -a yourpassword
# 测试原子加锁
SET mylock myrandomvalue NX PX 30000
# 返回 OK 表示加锁成功
# 模拟释放锁(Lua 脚本保证原子性)
EVAL "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 mylock myrandomvalue总结:通过 Docker 可在 5 分钟内完成 Redis 分布式锁基础设施搭建。开发环境用单节点 + Redisson/redislock 即可;生产环境建议采用 Redlock 多主节点 或 Redis Cluster + Redisson 方案,确保锁服务的高可用与强一致性。
到此这篇关于Docker实现容器化的分布式锁服务RedisLock的快速搭建的文章就介绍到这了,更多相关Docker分布式锁RedisLock搭建内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
