当前位置: 首页 > article >正文

锁明明还没过期,为什么另一个线程能抢进去?

做分布式开发的时候大家对 Redis 分布式锁应该都不陌生。为了防止锁死比如服务器突然断电锁永远不释放我们通常都会给锁加一个过期时间TTL。写代码的时候我们心里的算盘是这样打的❝“我的业务逻辑跑完只需要 200 毫秒但我为了保险给锁设了 10 秒的过期时间。这 10 秒够我跑 50 次了绝对稳如老狗。”但现实往往喜欢给人大嘴巴子。在线上高并发场景下你可能会遇到一种极其诡异的并发现象监控显示线程 A 还在执行业务逻辑锁的过期时间也没到理论上但线程 B 竟然大摇大摆地抢到了锁开始修改同一份数据。脏数据就这么产生了那这把明明还没过期的锁到底是怎么失效的。1. 案发现场为了复现这个问题我们先看一段看似标准的分布式锁伪代码// 1. 加锁设置 10秒 过期 if (redis.setnx(lock_key, thread_A, 10s)) { try { // 2. 执行业务逻辑 (预计 200ms) doBusiness(); } finally { // 3. 释放锁 // (这里通常会校验是不是自己的锁先省略) redis.del(lock_key); } }这段代码在 99.99% 的时间里都能完美工作但你的价值往往就是去解决那 0.01% 疑难问题。直到有一天服务器负载突然飙升应用触发了一次严重的Full GC或者宿主机发生了短时间的卡顿。就在这瞬间事故发生了。 欢迎加入小哈的星球你将获得:专属的项目实战多个项目 / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论新项目《Spring AI 项目实战》正在更新中..., 基于 Spring AI Spring Boot 3.x JDK 21;《从零手撸仿小红书微服务架构》 已完结基于 Spring Cloud Alibaba Spring Boot 3.x JDK 17..., 点击查看项目介绍演示地址http://116.62.199.48:7070/《从零手撸前后端分离博客项目全栈开发》2期已完结,演示链接http://116.62.199.48/;专栏阅读地址https://www.quanxiaoha.com/column截止目前累计输出 100w 字讲解图 4013 张还在持续爆肝中..后续还会上新更多项目目标是将 Java 领域典型的项目都整一波如秒杀系统, 在线商城, IM 即时通讯Spring Cloud Alibaba 等等戳我加入学习解锁全部项目已有4500小伙伴加入2. 时间被冻结我们总以为时间是连续的、均匀流逝的。但在计算机的世界里尤其是 Java 的世界里时间是可以暂停的。导致锁失效的真凶正是 JVM 的STWStop-The-World机制。我们把时间放慢看在微观的时间轴上到底发生了什么(0s) 线程 A 成功拿到锁过期时间10s。(0.1s) 线程 A 刚开始执行doBusiness()才跑了一行代码。(0.2s)事故来了JVM 触发了一次耗时极长的 Full GC可能是因为内存泄漏或者堆太大回收慢。此时JVM 暂停了包括线程A在内所有工作线程线程 A 停在了第 0.2s它觉得自己才刚开始跑。但Redis 服务端的时间并没有停Redis 那边的倒计时还在正常走。(10.2s) 10 秒过去了Redis 发现lock_key过期了于是删除了这个 Key。(10.3s) 线程 B 进来请求加锁因为它发现 Redis 里没锁所以成功拿到了锁。(12s)Full GC 结束线程 A 被唤醒了。线程 A 完全不知道自己sleep 12 秒以为自己才跑 0.2s手里还攥着锁。于是线程 A 继续执行剩下的业务逻辑往数据库里写数据。(12.1s) 线程 B 同时也在写数据。结果线程 A 和 线程 B 同时在操作数据锁彻底失效了。这就是分布式系统中最经典的时间跳变问题你以为你拥有 10 秒其实在 STW 面前这 10 秒可能瞬间就蒸发了。3. 加长过期时间行不行很多同学的第一反应是那我就把过期时间设长点设成 10 分钟GC 总不能停 10 分钟吧这确实能降低概率但治标不治本。副作用大如果你的服务真的挂了锁要等 10 分钟才能释放这期间业务就瘫痪了。不可控你永远不知道下一次 STW 会停多久或者网络延迟会有多大。Watchdog 续命这是目前业界最主流的方案比如 Java 的Redisson客户端就实现了这个机制俗称看门狗。它的原理是线程 A 拿到锁过期时间设为 30s。Redisson 会在后台启动一个守护线程。每隔 10s默认是过期时间的 1/3守护线程就去 Redis 检查一下线程 A 还活着吗还持有锁吗如果还持有就自动把锁的过期时间重新续满到 30s。这样一来只要线程 A 的进程没挂即使正在 Full GC只要 GC 结束守护线程也会恢复工作去续期锁就永远不会过期。只有当线程 A 的机器彻底宕机守护线程也挂了锁才会因为没人续期而自动释放。4. 看门狗就万无一失了吗这就完了如果是普通的业务Redisson 确实够用了。但如果你做的是金融级的核心业务还要考虑到一种更极端的黑天鹅场景如果 GC 暂停发生在“最后一步”怎么办想象一下这个场景线程 A 拿到了锁看门狗也在正常工作。线程 A 查完数据库计算完了金额正准备执行最后一步UPDATE语句。突然超长 Full GC 来了。这次 GC 停得太久连后台的“看门狗”线程也被暂停了没法去 Redis 续期。Redis 里的锁过期了。线程 B 拿到了锁修改了金额。GC 结束线程 A 苏醒它不需要再请求 Redis而是直接把那条UPDATE语句发给了数据库。这又是数据覆盖了即使有看门狗在极端并发下分布式锁依然无法保证 100% 的互斥安全性。这也不能算 Bug这是 CAP 理论总是不能十全十美。在异步网络模型中仅仅依靠锁和时间是无法做到绝对安全的。终极解法乐观锁要彻底解决这个问题我们不能光靠锁还得靠存储层数据库兜底。这个方案叫Fencing Token 栅栏令牌或者通俗点叫乐观锁/版本号。加锁时返回版本号线程 A 抢 Redis 锁的时候Redis 生成一个递增的数字 Token比如 33。带版本号更新线程 A 在操作数据库时必须带上这个 33。UPDATE accountSET money 100 WHEREid 1AND current_token 33; -- 甚至更简单的乐观锁 UPDATEaccountSET money 100, version version 1 WHEREid 1ANDversion old_version;校验如果中间有线程 B 抢占了锁拿到了 Token 34 并修改了数据线程 A 的 Token 33 就会变成旧版本数据库的更新操作就会失败影响行数为 0。写在最后回到标题的问题锁明明还没过期为什么会被别人抢走因为在分布式的世界里我的时间和大家的时间往往不是一回事。要好好的去理解这句话当你下次写分布式锁的时候对于剩下的那 1%如果你在做涉及钱的核心业务请务必加上数据库层面的乐观锁做最后的兜底。千万别太相信时间很多奇怪问题都是时间引起的。看完等于学会点个赞吧 欢迎加入小哈的星球你将获得:专属的项目实战多个项目 / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论新项目《Spring AI 项目实战》正在更新中..., 基于 Spring AI Spring Boot 3.x JDK 21;《从零手撸仿小红书微服务架构》 已完结基于 Spring Cloud Alibaba Spring Boot 3.x JDK 17..., 点击查看项目介绍演示地址http://116.62.199.48:7070/《从零手撸前后端分离博客项目全栈开发》2期已完结,演示链接http://116.62.199.48/;专栏阅读地址https://www.quanxiaoha.com/column截止目前累计输出 100w 字讲解图 4013 张还在持续爆肝中..后续还会上新更多项目目标是将 Java 领域典型的项目都整一波如秒杀系统, 在线商城, IM 即时通讯Spring Cloud Alibaba 等等戳我加入学习解锁全部项目已有4500小伙伴加入1. 我的私密学习小圈子从0到1手撸企业实战项目~ 2. 阿里二面什么是 MySQL 回表查询如何避免修订版 3. Nacos 点了下线为什么流量还是打到了停机的机器上 4. 如何画出一张优秀的架构图老鸟必备最近面试BAT整理一份面试资料《Java面试BATJ通关手册》覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式点“在看”关注公众号并回复 Java 领取更多内容陆续奉上。PS因公众号平台更改了推送规则如果不想错过内容记得读完点一下“在看”加个“星标”这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀谢谢啦

相关文章:

锁明明还没过期,为什么另一个线程能抢进去?

做分布式开发的时候,大家对 Redis 分布式锁应该都不陌生。为了防止锁死,比如服务器突然断电,锁永远不释放,我们通常都会给锁加一个过期时间(TTL)。写代码的时候,我们心里的算盘是这样打的&#…...

OpenClaw版本升级:nanobot无缝迁移指南

OpenClaw版本升级:nanobot无缝迁移指南 1. 升级前的准备工作 上周我在本地开发环境遇到了一个棘手的问题——现有的nanobot实例无法兼容最新的OpenClaw框架功能。这迫使我不得不面对版本升级这个"技术债"。经过三天的反复尝试,我总结出一套可…...

番茄小说下载器:用Rust打造的全能离线阅读解决方案

番茄小说下载器:用Rust打造的全能离线阅读解决方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 你是否曾经在地铁上看到精彩的小说章节却因网络信号不佳而中断&…...

Win10下Excel数据源配置全攻略:ODBC连接保姆级教程(含常见问题解决)

Win10下Excel数据源配置全攻略:ODBC连接保姆级教程(含常见问题解决) 在数据分析与报表自动化领域,Excel作为最普及的工具之一,经常需要与其他系统进行数据交互。ODBC(开放数据库互连)技术就像一…...

SenseVoice-Small模型在软件测试自动化中的应用:语音交互功能测试

SenseVoice-Small模型在软件测试自动化中的应用:语音交互功能测试 最近和几个做软件测试的朋友聊天,他们都在抱怨同一个问题:现在带语音交互功能的App和系统越来越多了,什么手机助手、智能车机、智能家居控制,测试起来…...

Web前端开发毕业设计项目实战:从零搭建一个高可用、可扩展的TodoList应用

很多同学在做前端毕业设计时,常常感觉无从下手,要么功能太简单显得单薄,要么技术选型混乱,代码写得像“一锅粥”,答辩时被老师问得哑口无言。今天,我们就来一起动手,从零搭建一个结构清晰、技术…...

SEO_从零开始,手把手教你制定SEO优化方案(216 )

SEO:从零开始,手把手教你制定SEO优化方案 在当今互联网时代,搜索引擎优化(SEO)已经成为任何网站希望获得高流量和高曝光的关键。对于新手来说,SEO可能看起来复杂且充满谜团。本文将从零开始,手把手教你如何…...

68聊天数据恢复实战:从误删到完整找回的解决方案

1. 当68聊天记录消失时,先别慌! 那天我正在整理手机内存,手指一滑不小心把整个68聊天对话框给删了——里面存着半年多的客户沟通记录和重要文件传输记录。相信很多朋友都遇到过类似的场景:可能是系统升级后聊天记录不见了&#xf…...

毕设程序java基于的动漫分析与交流平台 基于Spring Boot的二次元文化社区与作品分享系统 Java驱动的ACG内容聚合与互动服务平台

毕设程序java基于的动漫分析与交流平台31sl5luf(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着互联网技术的飞速发展和Z世代文化消费的崛起,动漫产业已从边缘亚文…...

sguard_limit:智能优化游戏体验的系统资源管理工具

sguard_limit:智能优化游戏体验的系统资源管理工具 【免费下载链接】sguard_limit 限制ACE-Guard Client EXE占用系统资源,支持各种腾讯游戏 项目地址: https://gitcode.com/gh_mirrors/sg/sguard_limit 1. 性能瓶颈解析 1.1 游戏玩家的共同困扰…...

Ollama部署Phi-3-mini全攻略:从安装到提问,新手友好图文指南

Ollama部署Phi-3-mini全攻略:从安装到提问,新手友好图文指南 想体验一个轻量级但能力不俗的AI助手吗?今天我们来聊聊如何用最简单的方式,把微软出品的Phi-3-mini模型部署起来,让它帮你写代码、回答问题、甚至进行创意…...

Stable Diffusion显存不够?5个你没想到的省显存技巧(实测可跑24GB模型)

Stable Diffusion显存优化实战:5个突破性技巧释放GPU潜力 当你在深夜赶制商业项目,Stable Diffusion突然弹出"CUDA out of memory"的红色警告,那种绝望感每个AI创作者都懂。我曾在RTX 4090上加载24GB的动漫风格模型时,发…...

如何利用Metabase实现联邦学习驱动的智能数据分析:三步入门指南

如何利用Metabase实现联邦学习驱动的智能数据分析:三步入门指南 【免费下载链接】metabase metabase/metabase: 是一个开源的元数据管理和分析工具,它支持多种数据库,包括 PostgreSQL、 MySQL、 SQL Server 等。适合用于数据库元数据管理和分…...

Java PPT自动化:从数据到演示文稿的智能生成

1. 为什么需要Java PPT自动化? 想象一下这样的场景:每周五下午,市场部的同事都会准时发来一封邮件,要求你根据本周的销售数据生成一份PPT报告。数据来自CRM系统,包含几十个SKU的销售额、增长率、区域分布等信息。你需要…...

WinUtil终极指南:10分钟掌握Windows系统管理与优化工具

WinUtil终极指南:10分钟掌握Windows系统管理与优化工具 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil WinUtil是一款强大的Windo…...

CentOS 7下Google Chrome离线安装全攻略(附依赖包下载清单)

CentOS 7下Google Chrome离线安装全攻略(附依赖包下载清单) 在企业级Linux环境中,CentOS 7因其稳定性和安全性仍然是许多组织的首选。然而,当需要在隔离网络环境下部署现代浏览器时,依赖关系往往成为技术人员的噩梦。…...

如何在10分钟内掌握SASM:终极汇编语言开发环境完整指南

如何在10分钟内掌握SASM:终极汇编语言开发环境完整指南 【免费下载链接】SASM SASM - simple crossplatform IDE for NASM, MASM, GAS and FASM assembly languages 项目地址: https://gitcode.com/gh_mirrors/sa/SASM SASM(SimpleASM&#xff09…...

3分钟上手!免费足球数据宝库football.json完全指南

3分钟上手!免费足球数据宝库football.json完全指南 【免费下载链接】football.json Free open public domain football data in JSON incl. English Premier League, Bundesliga, Primera Divisin, Serie A and more - No API key required ;-) 项目地址: https:/…...

企业级智能客服系统实战:基于RAG与语义检索的架构设计与避坑指南

最近在做一个企业级智能客服系统的项目,客户对传统客服的响应速度和知识更新效率很不满意。我们团队尝试了多种方案,最终决定采用RAG(检索增强生成)结合语义检索的技术路线。今天就来分享一下我们的实战经验,特别是架构…...

别让AI被‘带坏’:手把手教你用开源工具复现大模型越狱攻击(附防御实战)

大模型安全攻防实战:从开源工具复现到防御策略部署 当ChatGPT在2022年底掀起AI浪潮时,很少有人预料到三年后的大模型会面临如此复杂的对抗攻击。作为一名长期从事AI安全测试的工程师,我亲眼见证了攻击手段从最初的简单提示注入发展到如今的神…...

htcw_esp_panel:ESP32嵌入式显示与触摸的编译期硬件抽象框架

1. htcw_esp_panel:面向嵌入式显示与人机交互的全栈式硬件抽象层htcw_esp_panel 是一个专为 ESP32 系列 SoC(包括 ESP32-S2/S3/C3/P4)设计的轻量级、可配置化硬件抽象库。它并非简单的驱动封装,而是一套覆盖显示、触摸、按键、SD …...

RFdiffusion 安装后别急着关!手把手带你解读生成的 .pdb 和 .trb 文件,并接入 ProteinMPNN 完成设计

RFdiffusion 实战进阶:从骨架生成到完整蛋白质设计的全流程解析 当你第一次看到 RFdiffusion 生成的 .pdb 文件时,可能会感到既兴奋又困惑——那些蓝色的骨架线条代表着什么?如何将这些抽象的结构转化为具有生物功能的蛋白质?本文…...

OpenClaw Graph Memory 知识图谱深度解析:告别 AI 记忆困境,实现去中心化自我改进!

当 AI 助手频繁出错、反复试错消耗大量 token;当跨对话的宝贵经验第二天就消失无踪;当某个 Skills 学到的孤岛知识点无法迁移——这些问题是否困扰着你?OpenClaw 开源项目 Graph Memory 登场,用知识图谱颠覆传统记忆方案&#xff…...

Xinference-v1.17.1快速部署Web应用:Flask集成指南

Xinference-v1.17.1快速部署Web应用:Flask集成指南 1. 引言 想给自己的AI模型快速搭建一个Web界面吗?今天咱们就来聊聊怎么把Xinference-v1.17.1这个强大的AI推理引擎集成到Flask Web应用中。不需要复杂的架构设计,也不用担心API对接问题&a…...

vDisk课表同步指南:Windows/Linux平台配置详解

vDisk课表同步指南:Windows/Linux平台配置详解本指南旨在为使用 vDisk IDV 云桌面解决方案的学校和培训机构,提供一份详尽的 vDisk 课表同步配置指南,重点介绍 Windows 和 Linux 平台下的配置要点。通过本文,您将了解如何利用 Exc…...

PowerShell自动化批量修改注册表路径:解决用户文件夹重命名后的遗留问题

1. 为什么需要批量修改注册表路径 最近帮同事处理了一个典型的Windows系统问题:他的用户文件夹最初使用了中文命名,导致各种开发工具和环境频繁报错。这个问题其实很常见,特别是当我们需要重命名用户文件夹时,虽然修改了系统路径&…...

3个维度解析Outfit字体:构建跨平台设计系统的开源解决方案

3个维度解析Outfit字体:构建跨平台设计系统的开源解决方案 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts 在数字化设计领域,字体作为视觉传达的核心元素,直接…...

深度学习项目训练环境惊艳效果:同一镜像下AlexNet/VGG/ResNet/EfficientNet对比训练

深度学习项目训练环境惊艳效果:同一镜像下AlexNet/VGG/ResNet/EfficientNet对比训练 你是不是也遇到过这样的烦恼?想复现一个经典的深度学习模型,光是配环境就花了大半天,各种版本冲突、依赖缺失,最后代码还没跑起来&…...

小龙虾(openclaw) + 微信 + GIS,把专业GIS塞进聊天框!

微信不仅是社交工具,更成了空间信息服务“飞入寻常百姓家”的关键入口。当AI驱动的GIS自动化与国家级战略支撑在微信生态里汇合,我们终于有机会让每个人都能像发消息一样,调用专业空间能力,这背后是触达、效率与安全的巨大跃升。一…...

ANSYS Workbench ACT插件 FE Info 实战指南:从安装调试到高效查询

1. 为什么你需要FE Info插件 在ANSYS Workbench中进行有限元分析时,经常会遇到需要查询节点编号、单元信息或者测量距离的情况。比如设置耦合约束时,需要精确知道两个节点的距离;验证网格质量时,需要快速定位特定单元;…...