ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

分布式接口限流 + 分布式锁

分布式接口限流 + 分布式锁 分布式接口限流系统分布式限流功能性需求知识点详细讲解限流本质限制单位时间内接口访问次数防止爬虫、批量请求、大促峰值流量打垮服务、第三方短信通道。分布式场景难点多台服务集群部署如果只做单机本地限流每台机器独立计数总流量会叠加超限必须借助 Redis 实现全集群统一计数。功能性需求分为 6 条每条对应线上真实业务风险多维度限流不能只限制手机号商户、IP、全局接口都要独立管控不同维度负责不同防护目标。分级管控不同接口业务风险不同验证码极易被刷限制严格营销短信是正常业务限制宽松不能一刀切设置相同阈值。动态调整规则线上运营活动变更、爬虫攻击强度变化需要随时改限流上限、拉黑账号修改后立刻生效不能重启服务发布代码。友好返回提示被拦截后不能直接抛出 500 服务器异常前端展示通俗易懂提示提升用户体验。黑名单拦截针对持续恶意刷接口的 IP / 手机号支持临时封禁、永久封禁优先拦截减少 Redis 计算压力。分布式计数统一多台服务器同时接收请求计数数据存在共享 Redis所有节点共用一套统计数据不会出现 “单机没超限、整体超限”。生活化举例小区门禁访客登记限流场景类比 小区 短信平台访客 接口请求多维度管控按人手机号、楼栋商户、车牌IP三种登记限制分级管控快递外卖频繁进出验证码10 分钟最多进 3 次业主探亲营销短信一天可多次动态调整节假日访客多临时放宽登记上限有推销人员就收紧物业在中控屏直接改规则不用改造门禁系统友好提示访客超限保安温和告知 “稍后再来”不是直接不让进门黑名单发小广告人员永久禁止进入分布式统一计数小区多个大门多服务节点共用一套访客登记台账Redis不会东门登记 3 次、西门再登记 3 次合计超标。需求分类表格需求分类需求内容解决的线上问题多维度限流手机号 / 商户 / IP / 全局 4 种粒度独立计数单一维度防护存在漏洞爬虫切换 IP、换商户刷接口分级管控不同接口配置不同访问阈值统一阈值会导致验证码被刷爆或正常短信业务被误拦截动态调整规则阈值、黑名单实时生效无需重启服务活动、爬虫突发场景下调整规则成本极高停机影响业务友好返回提示限流拦截返回业务文案不抛 500用户投诉、前端页面报错混乱黑名单机制临时 / 永久封禁恶意 IP、手机号恶意请求反复占用 Redis 计算资源浪费性能分布式统一计数集群节点共享计数数据单机限流叠加整体流量击穿第三方短信通道简易流程示意图四大限流算法原理、优缺点与业务选型知识点详细讲解限流算法是实现流量控制的底层数学逻辑不同算法处理突发流量的能力、性能、实现难度差异很大分布式项目不能随便选用需要结合业务场景匹配。核心评判指标是否存在流量突刺、能否支持突发流量、实现复杂度、分布式适配性。1固定窗口算法核心逻辑把时间切成一段一段固定区间比如 1 分钟为 1 个窗口每个窗口单独维护计数器窗口结束直接清零重新计数。问题窗口临界点会出现流量突刺。例窗口 59 秒进来 99 个请求下一秒新窗口又涌入 99 个瞬间总流量远超阈值直接压垮服务。2滑动窗口RedisLua 实现核心逻辑将一个大窗口拆分为多个极小的滚动子窗口实时剔除过期请求只统计最近一段时间内的全部访问记录流量曲线平滑不存在临界突刺。分布式友好借助 Redis 有序集合 zsetLua 原子脚本多服务节点共用一套统计数据是互联网核心业务首选。3漏桶算法核心逻辑把接口比作水桶请求不断进水系统以固定匀速出水处理请求。进水速度大于出水速度水桶装满就拒绝新请求。特点强制削峰不允许任何突发流量哪怕是正常业务高峰期流量上涨也会被拦截适合消费端限流不适合前端业务接口。4令牌桶算法核心逻辑后台定时匀速往桶里投放令牌每处理 1 条请求消耗 1 个令牌桶内存有令牌则直接放行无令牌则拦截。特点桶内积攒令牌后可短时承载大量突发正常流量适合网关层全局限流兜底实现逻辑复杂需要定时任务维护令牌。生活化举例把平台接口比作景区检票口阈值设定 1 分钟最多放行 100 人固定窗口每 60 分钟清一次登记本。第 59 秒放 99 人01 分 00 秒本子清零瞬间又涌入 99 人检票口瞬间挤爆流量突刺。滑动窗口只保留最近 60 秒内所有游客记录每秒删掉 1 秒前的旧记录任何时刻统计都不会瞬间超标人流平稳。漏桶景区规定每分钟只放行 20 人哪怕节假日正常游客暴增也只能慢慢排队不允许短时大批量放行。令牌桶工作人员每分钟提前发放 20 张通行票票攒多了节假日可一次性放行大批游客兼顾平稳和突发需求。四大算法对比表格限流算法核心优势核心缺陷本短信项目适配场景固定窗口代码最简单内存开销极低窗口边界流量突刺易击穿服务内部后台低管理接口非核心链路Redis-Lua 滑动窗口流量平滑无突刺支持分布式集群统一计数少量 Redis 网络、内存开销短信下发、领券核心接口主方案漏桶算法强制削峰流量绝对平稳无法承接业务正常突发流量用户体验差RabbitMQ 消费者异步限流令牌桶算法支持短时业务突发流量逻辑复杂需要定时任务维护令牌网关全局限流兜底算法简易流程图滑动窗口项目主方案限流五层分层架构设计知识点详细讲解为了解耦、方便维护、方便迭代扩展项目把限流完整能力拆分为五层每层只做自己单一职责符合单一职责设计思想控制层拦截器层所有 HTTP 请求进来最先经过这一层统一做限流校验入口。不需要每个接口单独写限流代码全局拦截统一处理减少重复开发。业务层规则管理层负责限流规则 CRUD、黑名单增删改查、拦截数据统计上报、告警触发。提供后台管理页面操作入口运营可在线修改阈值、拉黑恶意账号。工具层通用封装层封装 Lua 脚本、Redis 操作工具类、滑动窗口计数通用方法。上层业务只需要调用工具方法不用关心 Redis 底层 zset、原子脚本细节。中间件层存储 防护层包含两个核心中间件Redis分布式统一计数、Sentinel本地降级限流兜底。所有分布式计数数据存在 RedisRedis 故障自动切本地 Sentinel 限流。存储层持久化层MySQL 持久化保存所有限流规则、黑名单记录。Redis 只做临时计数缓存重启丢失数据不影响配置配置永久存在数据库。分层核心好处解耦修改 Lua 脚本只动工具层调整规则页面只动业务层可替换Redis 故障可切换 Sentinel新增限流算法只扩展工具层易维护定位问题时按层级排查快速区分是拦截器、Redis 还是配置问题。生活化举例类比商场安保限流管控分层控制层 商场入口安检闸机所有人进门必须先过闸机统一拦截入口业务层 安保办公室登记黑名单、设置每日进场人数上限、统计每日拦截人数工具层 手持登记终端专门用来登记入场时间、统计人数闸机不用自己做计算中间件层 中控数据库 备用手持登记本主数据库记录全部访客数据库坏了用纸质本子临时登记兜底存储层 档案柜永久保存黑名单、每日限流标准断电数据不丢失。五层架构分层职责表分层核心组件负责工作控制层SpringMVC 全局拦截器请求统一拦截调用限流工具拦截后返回友好提示业务层LimitRuleService、BlackListService规则增删改查、黑名单管理、拦截量统计、钉钉告警工具层RedisLimitUtil、Lua 脚本文件封装滑动窗口原子计数逻辑屏蔽 Redis 底层细节中间件层Redis 集群、SentinelRedis 分布式计数Redis 宕机时 Sentinel 本地限流兜底存储层MySQL limit_rule、black_list 表持久化存储限流阈值、黑名单数据永久保存配置完整全链路流程项目架构SpringCloud 微服务 全局拦截器 Nacos 配置 Redis 黑名单 / 滑动窗口限流 Sentinel 熔断降级 MQ批量场景区分 Seata AT 分布式事务 MySQL 业务库 分两条链路链路 A单条实时短信生成同步接口完整走限流、黑名单、熔断、AI 调用、分布式事务、数据库操作链路 B批量短信任务异步 MQ仅补充异步分支主体限流逻辑一致链路 A单条同步 AI 短信生成完整全流程阶段 1前端请求发起 网关层预处理前端页面携带登录 Token、商户 ID、用户手机号、客户端 IP、活动需求参数发起 HTTP 请求到网关 Gateway网关统一操作校验 Token 合法性未登录直接返回 401提取公共标识userPhone、merId、clientIp、接口路径网关内置第一层 Sentinel 全局限流粗粒度保护整个服务集群网关校验不通过直接拦截不转发后端业务服务校验通过转发至短信业务服务。阶段 2业务服务全局拦截器控制层统一黑名单 限流前置校验请求进入 SpringMVC 全局拦截器所有接口统一一套逻辑无重复代码提取网关透传的标识手机号、商户 ID、IP、接口名步骤 1黑名单校验查 Redis 布隆过滤器 Set 缓存不查 MySQL匹配到黑名单手机号 / IP / 商户记录 ELK 拦截日志返回友好提示流程直接终止不进入业务无黑名单进入下一步步骤 2读取本地内存中 Nacos 缓存的限流规则服务启动监听 Nacos阈值加载本地不远程反复拉取获取当前接口配置阈值如验证码 10 分钟 3 次、短信接口单商户 24h 上限步骤 3执行 RedisLua 滑动窗口分布式限流原子脚本Lua 内部逻辑 ① zset 存入当前时间戳② 删除窗口过期数据③ 统计有效访问次数计数 阈值触发限流拦截埋点日志推送限流钉钉告警直接返回提示计数 ≤ 阈值放行进入下一层附加兜底Redis 集群宕机 / 超时自动切换 Sentinel 本地滑动窗口限流降级保障不被流量打垮。阶段 3进入 Controller 接口方法Sentinel 资源熔断监控接口方法打上 Sentinel 资源注解资源名区分sms_single单条、sms_batch批量Sentinel 实时统计该资源 QPS、错误率、平均耗时判断熔断状态若当前资源处于熔断窗口期此前 AI 接口大量超时 / 报错直接走本地降级逻辑不调用大模型熔断器关闭正常状态继续执行业务代码。阶段 4业务层前置安全校验AI 模块专属Prompt 注入关键词检测拦截恶意篡改 AI 规则的输入用户输入前置敏感词过滤提前拦截违规文案节省 AI 调用成本参数合法性校验商户状态、活动时间、短信内容长度校验参数非法直接返回流程终止。阶段 5调用 AI 能力自研 Agent / Dify 二选一分支 1自研 LangChain4j Agent从 Nacos 读取动态 Prompt 模板填充前端传入行业、禁用词占位参数Agent 自主拆解需求通过 Function Calling 调用自定义工具查询商户短信额度、活动合规规则工具方法同样受 Sentinel 监控工具调用频繁报错也会触发熔断组装完整请求调用第三方大模型 API。分支 2对接 Dify 平台后端封装 Dify Client携带 Nacos 配置的 api-key 内部调用HTTP 请求 Dify 接口同样被 Sentinel 监控超时、5xx 报错计入熔断统计。阶段 6AI 结果后置处理二次敏感词审核校验 AI 生成短信文案存在违规词标记失败统计 inputToken、outputToken组装统计实体SkyWalking 埋点记录整条链路耗时、各节点耗时、错误标识ELK 全量存储入参、AI 返回内容、Token 消耗、限流 / 熔断标记。阶段 7熔断降级兜底分支AI 调用异常时触发当大模型 / Dify 接口超时、报错达到阈值熔断器打开一级降级切换备用大模型密钥 / 备用厂商接口重试备用渠道同样故障二级降级读取 MySQL 预制行业短信模板模板读取异常三级兜底返回通用故障提示文案所有降级行为单独埋点日志高频触发推送钉钉故障告警。阶段 8开启 Seata AT 分布式事务多库 / 多表统一事务管控业务涉及多张业务表、多微服务数据修改使用 Seata 保证要么全部入库成功要么全部回滚GlobalTransactional 开启全局事务生成全局 XID传递到所有分支服务分支事务 1写入ai_generate_recordAI 生成记录表商户 ID、手机号、原始需求、生成文案、Token 消耗、限流 / 熔断标记分支事务 2更新merchant_sms_quota商户短信当日剩余额度分支事务 3写入token_cost_logToken 费用消耗统计表分支事务执行判断所有分支无异常Seata 提交全局事务释放各分支锁数据持久落库任意分支 SQL 异常 / IO 失败触发全局事务回滚撤销所有分支已执行的数据库操作恢复数据原始状态事务异常埋点批量推送钉钉告警记录错误堆栈到 ELK。阶段 9数据返回前端封装统一返回体携带生成的合规短信文案前端展示 若中途任意环节拦截黑名单、限流、熔断降级、事务异常返回对应提示信息。链路 B批量短信任务异步 MQ补充差异流程前端提交批量任务请求同样先走网关 全局拦截器黑名单 限流校验校验通过后Controller 开启本地事务数据库插入ai_task批量任务表状态 处理中发送持久化消息至 RabbitMQ数据库入库成功再发送消息避免消息发送成功但任务记录丢失接口立刻返回「任务提交成功」MQ 消费者监听队列消费消息时消费者端漏桶限流控制消费速率消费内部重复执行参数校验→Sentinel 熔断→AI 生成→合规审核批量多商户数据修改启用 Seata 分布式事务单商户生成失败仅回滚本条数据不影响整批AI 处理完成更新任务表状态为完成 / 异常消息处理失败、重试 3 次仍报错转入死信队列运维后台可重跑消费阶段事务异常本地分支回滚消息重回队列重试。全链路完整流程图多维度限流 Key 设计 Redis 缓存优化方案知识点详细讲解1多维度限流 Key 设计分布式限流需要区分不同限制维度通过Redis Key 前缀 业务唯一标识隔离计数数据互不干扰支持同时多种限制叠加生效。 四种核心维度对应不同业务防护目标手机号维度防止单手机号疯狂刷验证码、短信接口商户 ID 维度控制单个商家每日短信发送总量避免单一商户占用通道资源客户端 IP 维度拦截爬虫、批量脚本刷接口全局接口维度管控平台整体并发上限保护第三方短信通道不被运营商封禁。Key 统一格式规范limit:维度标识:业务唯一值每个 Key 对应独立 zset 滑动窗口窗口过期时间和业务限制时长保持一致如验证码 10 分钟、短信 24 小时。2黑名单缓存优化方案如果每次请求直接查询 MySQL 黑名单高并发下会产生大量磁盘 IO拖垮数据库优化分层设计持久层MySQLblack_list表永久存储黑名单手机号 / IP / 商户、封禁类型、过期时间缓存层Redis Set 集合存储完整黑名单精准匹配布隆过滤器前置快速过滤绝大部分正常请求直接放行减少 Set 查询缓存刷新机制 运营后台新增 / 删除黑名单 → 修改 MySQL 数据 → 主动推送消息刷新 Redis 缓存实时生效兜底Redis 缓存丢失时定时任务全量同步 MySQL 黑名单至 Redis。生活化举例类比快递驿站取件限流手机号维度limit:phone:13800138000同一个人 10 分钟最多取 3 个验证码包裹商户维度limit:mer:10086门店商家一天最多寄 500 条营销短信IP 维度limit:ip:192.168.1.1同一个网络地址禁止频繁批量查询全局limit:global:smsSend全驿站一天短信总发送上限 10 万条黑名单类比驿站拉黑恶意取件人 黑名单档案存档案室MySQL前台登记台有电子黑名单缓存Redis 布隆 Set不用每次翻纸质档案前台一眼判断是否拉黑。限流 Key 明细表格限流维度Redis Key 模板窗口过期时间业务作用手机号limit:sms:phone:{phone}10min验证码防刷限制单人频繁获取验证码商户 IDlimit:merchant:{merId}24h控制单商户每日短信总额度客户端 IPlimit:ip:{clientIp}1h拦截爬虫、脚本批量刷接口全局接口limit:global:smsSend1min控制平台短信整体并发保护第三方通道黑名单缓存流转流程图线上优化手段 限流故障兜底方案线上性能优化手段整套 Redis Lua 滑动窗口限流存在 Redis 网络 IO、内存开销线上配套多重优化降低损耗1.Lua 原子脚本执行多条 Redis 操作删过期数据、写入时间戳、统计数量整合在一段 Lua 脚本一次性执行仅一次网络往返避免多次 Redis 命令并发导致计数错乱、网络耗时叠加。2.Zset 自动过期清理每条限流 Key 设置和窗口时长一致的过期时间长期无访问的冷 Key 自动被 Redis 淘汰不会无限堆积占用内存。3.布隆过滤器前置拦截黑名单正常用户绝大部分不会命中黑名单布隆过滤器 O (1) 快速过滤减少 Redis Set 查询次数减轻 Redis 压力。4.Nacos 动态配置灰度调整限流阈值全部托管 Nacos支持灰度调整部分商户 / 接口阈值配置变更实时推送到服务本地内存无需重启项目也不用每次请求远程拉取配置。5.全链路监控告警统计ELK 采集每日拦截请求数量设置阈值当日拦截量突增自动钉钉推送告警提前发现爬虫攻击。故障兜底方案Redis 集群宕机 / 超时不可用分布式限流完全依赖 Redis如果 Redis 故障统一切换Sentinel 本地滑动窗口限流做兜底防护切换触发条件Redis 连接超时、集群宕机、读写报错兜底逻辑放弃分布式统一计数单台服务独立本地内存计数缺陷集群多节点流量会叠加限流精度下降但能防止服务被打垮恢复机制定时探测 Redis 状态Redis 恢复后自动切回分布式 Redis 限流模式。生活化举例小区门禁限流优化 故障兜底类比Lua 原子脚本访客登记、清理过期记录、统计人数一次性办完不用分多次跑档案室Key 自动过期长期不进门的访客记录自动删除不堆积台账布隆过滤器大部分正常居民快速放行不用翻黑名单本子Nacos 动态配置物业中控屏直接修改每日访客上限不用更换门禁设备Redis 宕机兜底档案室系统断电保安改用纸质登记本临时限流精度不准但能防止人群拥挤。优化与兜底方案汇总表类型方案解决问题性能优化Lua 原子脚本合并操作多次 Redis 网络交互耗时高、并发计数不准性能优化Zset 设置过期时间冷 Key 堆积Redis 内存持续上涨性能优化布隆过滤器前置黑名单校验大量无效 Redis 查询Redis 负载高性能优化Nacos 本地缓存限流阈值频繁远程拉取配置、改规则需要重启服务监控优化ELK 统计拦截量 钉钉告警爬虫恶意刷接口无法及时感知故障兜底Redis 故障切换 Sentinel 本地限流Redis 不可用时无防护流量压垮服务Redis 故障切换流程图限流落地量化业务效果落地可量化业务指标做项目不能只说实现功能需要带数据体现价值全部贴合 AI 营销短信平台业务恶意爬虫拦截效果日均拦截刷短信、刷验证码请求 4.2 万次彻底避免第三方短信通道因高频刷量被运营商封禁流量平滑优化采用滑动窗口算法消除固定窗口临界流量突刺短信接口峰值流量平稳无瞬间超限打爆通道问题配置迭代效率提升限流阈值、黑名单规则修改从原先改代码重启服务30 分钟变为 Nacos 动态配置实时生效1 秒完成运营活动调整效率大幅提升故障兜底保障Redis 集群故障自动切换 Sentinel 本地限流线上从未出现无防护裸奔被流量打垮服务的情况运维告警能力拦截量突增自动钉钉告警爬虫攻击可在 5 分钟内感知并处置。生活化举例量化效果每日拦下 4 万黄牛恶意购票景区检票口不会瞬间挤满游客限流规则线上直接改不用停机改造闸机服务器断电有手持登记本兜底人流量暴涨会自动通知管理人员落地量化指标表格优化维度优化前问题优化后量化效果恶意爬虫防护脚本批量刷短信通道频繁被运营商限制日均拦截恶意请求 4.2 万次通道从未封禁流量稳定性固定窗口临界点流量突刺瞬时并发超标滑动窗口平滑流量无瞬时峰值击穿通道规则更新效率修改限流阈值需要改代码、重启服务耗时 30 分钟Nacos 动态配置1 秒实时生效无需重启故障防护能力Redis 宕机后无限流防护服务极易被打垮自动切换 Sentinel 本地限流线上无裸奔事故运维感知能力爬虫攻击只能人工查看日志发现滞后拦截量突增钉钉自动告警5 分钟内感知异常分布式锁系统分布式锁功能性 非功能性需求知识点详细讲解核心背景我们短信平台是 SpringCloud 集群多节点部署两类核心业务必须靠分布式锁解决并发问题1.定时营销短信任务Quartz 定时任务所有服务节点同时触发不加锁会集群重复执行重复下发大量营销短信造成通道浪费、用户骚扰2.优惠券领取 / 库存扣减高并发下多节点同时查询库存、扣减出现超发、库存负数业务数据不一致。单机 JVM 锁synchronized、Lock只对单台服务生效集群环境完全失效因此必须使用分布式锁让全集群共享一把锁。1功能性需求集群互斥同一时刻集群中只能有一个节点持有锁执行任务 / 扣库存自动过期防死锁服务宕机、线程卡死锁到时间自动释放不会永久锁住资源支持可重入同一线程多次加锁不会阻塞死锁比如方法嵌套调用加锁逻辑可自旋重试抢锁失败短暂休眠重试不疯狂空转消耗 CPU锁归属校验只能由加锁的线程解锁禁止其他线程恶意释放锁区分公平 / 非公平锁定时任务场景使用非公平锁性能更高。2非功能性需求高性能加锁、解锁 Redis 操作毫秒级不拖慢接口响应高可用Redis 主从切换、节点故障时尽量避免锁丢失数据安全杜绝死锁、锁提前失效、误解锁、库存超发四大经典问题可观测统计锁竞争次数、线程持锁时长异常告警。生活化举例商场限时优惠券发放 每日定时广播活动通知集群互斥商场多个广播室多服务节点同一时间只允许一间广播室播放活动通知否则重复播报扰民优惠券货架一次只能一个顾客拿券防止多个人同时拿走超出库存自动过期防死锁广播员中途突然离岗广播权限 10 分钟自动释放不会永久占用可重入广播室工作人员先拿到钥匙中途去隔壁配套房间不用归还钥匙再重新领取归属校验只有拿钥匙的广播员能归还外人不能强行开门归还自旋重试当前广播室被占用工作人员等几秒再尝试不一直拍打门。需求分类表格需求分类需求内容解决线上业务问题集群互斥多节点同一资源同一时间仅一个线程持有锁定时任务重复执行、优惠券库存超发自动过期锁设置过期时间宕机自动释放服务崩溃导致永久死锁资源一直锁定锁可重入同一线程多次加锁正常执行不阻塞多层方法嵌套加锁出现死锁阻塞业务线程归属校验解锁仅加锁线程能释放锁其他线程误删锁引发并发超发自旋重试抢锁抢锁失败短暂休眠重试无限制循环抢锁CPU 占满可监控统计持锁时长、竞争次数埋点统计无法定位长时间持锁、锁竞争激烈故障基础业务流程图定时任务场景三种分布式锁方案选型对比知识点详细讲解分布式锁主流三种实现方案适配不同并发量级、业务场景结合营销短信定时任务、优惠券高并发扣减场景做取舍。1.MySQL 悲观 / 乐观锁悲观锁select ... for update 行级排他锁事务未提交其他线程阻塞等待乐观锁表增加 version 版本号更新时校验版本版本不一致更新失败核心短板数据库磁盘 IO 性能差高并发场景大量阻塞吞吐量极低仅适合低并发兜底场景。2.Zookeeper 临时节点锁原理创建临时有序节点最小序号节点获得锁会话断开临时节点自动删除天然防死锁优点CP 强一致性锁可靠性极高短板Zookeeper 运维成本高频繁创建删除节点性能弱不适合优惠券高并发扣库存场景项目不选用。3.Redis Lua 实现 RedLock 可重入分布式锁项目核心方案原理通过 Lua 原子脚本完成加锁、重入计数、解锁逻辑基于 Redis 高性能内存操作优势毫秒级加解锁、支持可重入、可设置过期防死锁、支持自旋重试适配高并发定时任务、优惠券领券补充高可用采用 RedLock 多节点加锁过半节点加锁成功才算持有锁应对 Redis 主从切换数据丢失问题。生活化举例商场限量优惠券柜台锁MySQL 锁柜台办事必须排队等上一个人完整办完手续事务提交人多排队拥堵效率低Zookeeper 锁专门安保室登记排队号稳定性极强但登记流程繁琐、速度慢Redis 分布式锁前台电子门禁快速拿权限办事速度快没人操作会自动归还钥匙多人嵌套办事也不用反复交还钥匙。三种方案对比表格实现方案核心优点核心缺点本短信项目使用场景MySQL 悲观 / 乐观锁无需额外中间件实现简单磁盘 IO 性能差高并发阻塞严重吞吐量低优惠券低并发场景兜底方案Zookeeper 临时节点锁CP 强一致天然防死锁可靠性高性能弱运维复杂不适合高并发项目不选用Redis Lua RedLock 可重入锁内存操作毫秒级性能、支持可重入、过期防死锁、适配高并发需自行处理主从切换锁丢失问题定时营销任务、高并发领券核心方案选型决策流程图分布式锁五层分层架构设计知识点详细讲解为实现代码解耦、方便迭代维护、统一管控锁能力项目将分布式锁拆分为五层分层架构每层单一职责。1.控制层入口层定时任务、领券接口统一入口方法执行前统一加锁执行完毕释放锁不用每个业务手写重复加解锁代码可封装注解实现一键加锁。2.业务层业务逻辑层两类核心业务① Quartz 定时营销任务抢到锁后执行人群筛选、批量生成短信、投递 MQ抢锁失败直接终止任务防止集群重复推送② 优惠券领取库存扣减抢到锁后查询库存、扣减库存、记录领券日志无锁直接返回活动繁忙。3.工具层锁通用封装层封装 RedLock 工具类内置 Lua 加锁脚本、解锁脚本、自旋重试逻辑、看门狗续期线程上层业务只调用tryLock()/unLock()屏蔽 Redis 底层原子脚本细节支持自定义锁过期时间、自旋次数。4.中间件层存储层Redis 集群负责存储锁 Key、线程标识、重入计数支持 RedLock 多节点过半校验解决主从切换锁丢失问题Lua 脚本全部在 Redis 服务端原子操作避免并发错乱。5.存储层持久化层 MySQL定时任务执行记录表、优惠券库存表、用户领券记录表锁只做并发控制最终业务数据持久落库配合 Seata 分布式事务保证数据一致性。分层核心价值解耦修改 Lua 脚本、调整自旋重试规则只改动工具层不侵入业务代码复用定时任务、领券、库存扣减共用同一套锁工具易排查锁超时、死锁、误删等问题按层级快速定位。生活化举例商场限量优惠券柜台管控分层控制层 柜台门口闸机所有人领券 / 广播通知必须先过闸机申请权限业务层 柜台工作人员拿到权限后执行发券、登记操作没权限直接离开工具层 钥匙管理工具统一负责发放、回收钥匙自动延长使用时效中间件层 钥匙存放柜集中存放权限钥匙速度快存储层 纸质登记本领券记录、库存数量永久存档。五层架构分层职责表分层核心组件核心工作控制层定时任务入口、领券 Controller、自定义 DistLock 注解统一加锁拦截业务执行前后自动加锁、释放锁业务层SmsTaskService、CouponService定时批量短信生成、优惠券库存查询与扣减业务逻辑工具层RedisRedLockUtil、加 / 解锁 Lua 脚本、看门狗线程封装可重入加锁、自旋重试、解锁、锁自动续期能力中间件层Redis 集群、RedLock 过半校验机制内存存储锁信息原子执行 Lua 脚本提供分布式共享锁存储层MySQL task 任务表、coupon 库存表、user_coupon 领券表持久化业务数据搭配分布式事务保证数据一致Lua 加锁 解锁核心逻辑 四大经典线上问题解决方案知识点详细讲解1Lua 加锁脚本原子逻辑实现可重入锁 Key 为资源标识Value 存储「当前线程 ID 重入计数」脚本在 Redis 单线程原子执行无并发竞争问题判断锁 Key 不存在写入当前线程 ID、重入次数 1设置过期时间返回加锁成功Key 存在且持有者是当前线程重入次数 1刷新锁过期时间返回成功Key 属于其他线程返回抢锁失败进入自旋休眠重试。2Lua 解锁脚本原子逻辑防止误删他人锁先校验锁持有者线程 ID 是否等于当前执行线程不匹配直接返回禁止释放不属于自己的锁匹配重入次数 - 1重入次数减为 0删除锁 Key完全释放次数大于 0仅刷新过期时间。3四大高频线上问题完整解决方案1.死锁问题现象服务宕机、线程卡死锁永久不释放其他线程永远抢不到锁。解决所有锁强制设置过期时间宕机后 Redis 自动过期释放锁从根源杜绝永久死锁。2.不可重入问题现象同一线程嵌套多次加锁第二次直接抢锁失败阻塞业务。解决Value 记录线程 ID 计数同一线程重复加锁仅累加计数不会互斥阻塞。3.误解锁问题现象A 线程的锁到期自动释放B 线程抢到锁此时 A 执行完主动删锁把 B 的锁删掉引发并发超发。解决解锁 Lua 先校验线程归属只能删除自己线程持有的锁无法操作别人的锁。4.业务执行过长锁提前过期现象复杂批量短信任务执行耗时超过锁过期时间锁提前释放多节点同时执行业务数据错乱。解决开启看门狗续期线程定时检测锁状态锁未释放就自动延长过期时间业务执行完毕关闭看门狗。生活化举例仓库货物独占锁可重入管理员拿到仓库钥匙中途要去配套隔间办事不用归还钥匙再重新申领防误删只有拿钥匙的管理员能交还钥匙其他工作人员无权归还防死锁管理员突发离岗失联钥匙 10 分钟自动失效其他人可正常领用看门狗续期仓库盘点耗时很久系统自动延长钥匙有效期不用中途重新换锁。四大问题与对应方案对照表线上故障故障后果解决方案死锁定时任务永久阻塞、优惠券一直无法领取锁统一设置过期时间宕机自动释放不可重入多层嵌套加锁直接阻塞接口超时报错Lua 脚本记录线程 ID 重入计数支持重复加锁误解锁锁被其他线程删除并发导致库存超发、重复发短信解锁前校验线程归属非持有者禁止删锁业务超长锁过期锁提前释放多节点并行执行业务数据不一致看门狗后台线程自动续期锁过期时间加解锁核心流程图Redis 集群锁高可用优化 两大业务场景完整流程知识点详细讲解1Redis 主从架构原生缺陷普通单节点 / 主从锁存在风险 主线程加锁成功锁数据还未同步到从库此时主节点宕机、从库升级为新主新主无锁记录其他节点可重新抢到锁并发冲突出现重复发短信、优惠券超发。2RedLock 过半加锁高可用优化方案部署独立多台 Redis 节点非主从加锁时向全部节点执行 Lua 加锁脚本只有过半节点加锁成功才算真正持有分布式锁解锁同步删除所有节点的锁 Key兜底补充业务层增加幂等校验双重防护锁失效带来的数据错乱。3场景 1定时营销短信任务执行流程Quartz 集群所有节点同时触发定时任务通过DistLock注解自动执行 RedLock 抢锁自旋重试抢到锁启动看门狗续期执行人群筛选、批量生成短信、投递 RabbitMQ开启 Seata 分布式事务写入任务执行记录业务结束主动释放锁未抢到锁直接终止任务不执行任何业务避免集群重复群发异常兜底服务宕机锁超时自动释放下一轮定时可正常执行。4场景 2优惠券高并发领取流程含分布式事务用户请求领券接口控制层自动加分布式锁抢锁失败返回「活动繁忙请稍后重试」抢到锁开启 Seata AT 全局事务 ① 查询优惠券剩余库存 ② 库存 0 则扣减库存新增用户领券记录 ③ 库存 0 直接返回无券任意数据库操作异常Seata 全局回滚释放锁业务执行完毕Lua 脚本校验线程归属后解锁。生活化举例仓库多库房钥匙管控RedLock公司有 3 个独立库房领用权限需要至少 2 个库房登记成功才算拿到钥匙就算其中一间库房系统崩溃另外两间仍有记录不会出现多人同时占用货物盘点耗时久自动延期钥匙时效盘点完主动归还。高可用优化对照表问题解决方案作用Redis 主从切换锁丢失RedLock 多独立节点过半加锁才算成功主节点宕机、未同步锁数据也不会出现锁失效极端情况锁失效业务幂等校验 分布式事务锁失效导致并发写入时避免重复数据、库存超发业务执行时间过长看门狗线程持续续期锁过期时间防止任务未完成锁提前释放RedLock 加锁流程图落地量化业务效果业务指标优化前接入分布式锁优化后定时任务重复短信日均 2100 条重复下发重复下发条数 0优惠券库存超发大促频繁出现需人工修复库存完全杜绝超发问题加解锁耗时-平均 1ms无接口性能拖累并发故障死锁、超发、重复推送频发四大并发问题全部闭环解决
返回列表