docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker分布式锁RedisLock搭建

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 核心优势:

方案 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 yes

Redisson 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 核心逻辑:

五、关键避坑指南

坑点正确做法
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搭建内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文