SpringBoot 3.x中的的分布式锁与同步机制!

举报
bug菌 发表于 2025/08/25 15:35:40 2025/08/25
【摘要】 🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8 前言💡 一句话概括: 分布式系统环境下,如何确保多个进程不会同时访问...

🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

前言

💡 一句话概括: 分布式系统环境下,如何确保多个进程不会同时访问同一资源?Redis 和 ZooKeeper 是目前最常见的两种分布式锁方案,它们各有优缺点,今天我们就深入剖析它们的原理、实现方式以及最佳实践!

🌟 1. 前言:你是不是也被分布式系统的并发问题搞疯了?

在单机环境下,Java 的 synchronized 关键字 或 ReentrantLock 就能搞定多线程同步问题,然而在 分布式环境 里,事情可没那么简单!

场景想象:
假设你在运营一个电商平台,现在搞一个限时秒杀活动,5000 个用户同时冲进来抢购 100 台 iPhone,如果没有分布式锁,数据库可能会直接炸裂,订单数量可能远远超过库存!这就是典型的超卖问题!

于是,你开始寻找解决方案:

分布式锁,能保证同一时间只有一个服务实例能操作库存数据,其他请求要么等待,要么直接返回失败,从而避免超卖或数据混乱。

本篇文章将带你深入探讨 Redis 和 ZooKeeper 实现的分布式锁,并分析它们的优劣势,让你可以根据业务场景选择最合适的方案。

📖 2. 目录

  1. 🔐 分布式锁的概念与应用场景
  2. 使用 Redis 实现分布式锁
  3. 🏰 使用 ZooKeeper 实现分布式锁
  4. 🔄 解决分布式系统中的竞态条件与锁粒度
  5. 🛠️ 实战演练——用 Redis 和 ZooKeeper 解决秒杀超卖问题
  6. 🤔 总结与思考

🔐 3. 分布式锁的概念与应用场景

📌 3.1 什么是分布式锁?

分布式锁的核心目标是保证在分布式环境下,同一时间只有一个进程能访问某个资源

在单机环境下,我们可以使用 Java 的 synchronizedReentrantLock 来保证线程安全。但在分布式环境中,由于多个实例分布在不同的服务器上,必须使用一种可以跨多个节点协调的锁机制,这就是分布式锁

🚀 3.2 典型应用场景

  • 库存扣减(电商秒杀、商品限购)
  • 任务调度(确保定时任务不会被多个实例同时执行)
  • 订单去重(避免用户重复下单)
  • 支付幂等(确保用户的支付请求不会被多次执行)

⚡ 4. 使用 Redis 实现分布式锁

Redis 是当前实现分布式锁最常见的方案之一,因其高性能、简单易用,被大量企业采用。

🛠️ 4.1 基于 SETNX 的实现

最基本的 Redis 分布式锁是使用 SETNX(Set if Not Exists)命令来实现的:

public boolean tryLock() {
    long result = jedis.setnx("lock_key", "locked");
    if (result == 1) {
        jedis.expire("lock_key", 10); // 设置锁的过期时间,防止死锁
        return true;
    }
    return false;
}

public void unlock() {
    jedis.del("lock_key"); // 释放锁
}

⚠️ 问题:

  • 如果锁的持有者崩溃,锁可能永远不会释放(死锁问题)!
  • SETNX 不支持可重入锁!
  • 没有自动续期机制,导致锁可能在任务执行完成之前就被释放。

🔄 4.2 可重入锁的改进

可重入锁是指同一个线程可以多次获取同一把锁。为了解决 Redis 锁的可重入性,我们可以使用 UUID 作为锁的唯一标识:

private String lockValue = UUID.randomUUID().toString();

public boolean tryLock() {
    String result = jedis.set("lock_key", lockValue, "NX", "EX", 10);
    return "OK".equals(result);
}

public void unlock() {
    if (lockValue.equals(jedis.get("lock_key"))) {
        jedis.del("lock_key");
    }
}

这样可以确保只有创建锁的进程才能释放锁,避免误删其他线程的锁。

🚨 4.3 Redis 分布式锁的潜在问题

问题 解决方案
锁超时被误删 采用 Redisson 进行自动续期
锁无法可重入 使用 UUID 作为锁标识
多进程竞争锁 采用 RedLock 算法提高可靠性

🏰 5. 使用 ZooKeeper 实现分布式锁

📝 5.1 基于临时顺序节点的实现

ZooKeeper 实现分布式锁的原理是创建 临时顺序节点,然后按照顺序来执行任务。

public void tryLock() throws KeeperException, InterruptedException {
    String nodePath = zk.create("/lock_", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    List<String> children = zk.getChildren("/lock", false);
    Collections.sort(children);
    if (nodePath.equals("/lock/" + children.get(0))) {
        System.out.println("获取锁成功:" + nodePath);
    } else {
        System.out.println("获取锁失败,等待中...");
    }
}

🔍 5.2 ZooKeeper 分布式锁的优劣势

方案 优势 劣势
Redis 分布式锁 高性能,适用于高并发 存在过期时间控制问题
ZooKeeper 分布式锁 天然支持可重入锁 性能较低,依赖于 ZK 集群

🛠️ 6. 实战演练——用 Redis 和 ZooKeeper 解决秒杀超卖问题

场景: 我们要实现一个限量商品的秒杀功能,确保多个用户不会超卖商品库存。

public void seckill() {
    if (redisLock.tryLock()) {
        try {
            // 扣减库存
        } finally {
            redisLock.unlock();
        }
    }
}

🤔 7. 总结与思考

  1. Redis 适用于高并发场景,但要注意锁超时问题。
  2. ZooKeeper 更稳定,但性能相对较低,适合强一致性需求的任务。
  3. Redisson 是 Redis 锁的增强版本,推荐使用。
  4. 分布式锁不是万能的,在设计系统时要综合考虑业务需求。

希望这篇文章能帮你搞懂分布式锁的实现!🚀

🧧福利赠与你🧧

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」专栏(全网一个名),bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

✨️ Who am I?

我是bug菌(全网一个名),CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云多年度十佳博主/价值贡献奖,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。

-End-

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。