-
我把几个服务实例缩容下线了、本以为流量自然就不会再来,可接下来好几十秒里调用方还在大量报连接被拒绝、请求纷纷失败,我盯着监控纳闷那些实例明明已经停了,最后才想明白实例没了是一回事调用方什么时候知道它没了是另一回事这中间隔着一段谁也绕不开的传播延迟的深度复盘
我的服务部署了多个实例、注册在服务注册中心、调用方通过服务发现拿到实例列表再负载均衡分发请求。某次缩容我把其中几个实例直接停掉,想当然以为实例一停就从可用列表没了、流量自然只去剩下的健康实例。可现实是停掉后好几十秒里调用方持续报错——大量 connection refused、超时、成功率掉一截才慢慢恢复。我确认那些实例真停了却百思不得其解,查调用方日志发现它请求的目标 IP 正是已下线实例。直到…- 0
- 0
-
我的分布式服务时不时冒出莫名其妙的错——JWT 明明没过期却被判过期、跨节点的日志时间对不上、限流和缓存过期也乱套,排查半天才发现是集群里几台机器的时钟悄悄漂移了、各自的现在几点根本不一样的深度复盘
我有套分布式服务跑在好几台机器上,某段时间开始系统时不时冒出毫无规律又对不上号的错:有的用户带着明明没过期的 JWT 却被判令牌已过期、有的又用着本该过期的令牌畅通无阻;把几台机器日志按时间拼一起时间戳乱七八糟因果颠倒;基于时间的限流忽松忽紧、缓存有的提前过期有的迟迟不过期。这些错散落各处看着不相关,我查认证查缓存都没毛病。直到同时登上几台机器敲 date 才倒吸凉气:这几台机器系统时间各不相同,…- 0
- 0
-
我的下单接口偶尔会给同一个用户重复下两笔一模一样的单、甚至重复扣款,可我代码里明明每次只下一单,排查半天才明白是客户端超时重试、用户手抖多点了几下,让同一个请求被发了好几次、而我的接口压根没防着重复的深度复盘
我有个下单接口:接到请求就创建订单、扣一次款,逻辑清清楚楚一次请求一个订单。我自己测试点一下下一单完美无缺。可上线后客服陆续投诉:有用户只下了一单,系统却给他创建了两三笔一模一样的订单、重复扣了好几次款。我翻日志发现重复订单都来自短时间内几乎同时到达、内容完全相同的多个请求。我以为是并发 bug、循环写错,检查下单逻辑都没问题。顺着重复请求往上游追才恍然:问题不在接口处理一次请求的逻辑,而在同一个…- 0
- 0
-
我用消息队列解耦订单处理,以为一条消息只会被消费一次,结果某条扣库存的消息被重复消费了两次,库存莫名其妙被多扣了一份:一次没为消息重复投递做幂等、误把至少一次当成恰好一次的深度复盘
我用消息队列解耦订单流程:订单服务下单发消息,库存服务消费消息扣库存。我想当然地以为一条消息只会被消费一次,消费逻辑写得很直白:收到就扣。线上跑了一阵对账发现少量订单库存被扣了两次——只买 1 件却少了 2 件。翻日志才发现:那几条消息确实被同一个 messageId 消费了两遍。复盘 MQ 投递语义才恍然大悟:绝大多数消息队列默认是至少一次(at-least-once)投递,不是恰好一次(exa…- 0
- 0
-
我给下游调用加了失败自动重试本想让系统更可靠,结果某次下游只是变慢,重试却把流量放大了好几倍直接把它压垮:一次重试风暴拖垮整个链路的深度复盘
我有个服务要调下游接口,之前偶尔因下游抖动失败,我想加个重试吧、失败自动重试3次、成功率能高不少。平时确实好用。可那天下游因 GC 卡顿只是变慢了(响应 50ms 涨到 2 秒、没挂),我却眼睁睁看着它在几十秒内被打成彻底挂掉、整条链路雪崩。复盘才倒吸凉气:下游一变慢,大量请求超时失败,每个失败的请求立刻重试3次,本来1倍的流量瞬间变成3~4倍,把本来还撑得住的下游直接压垮;压垮后失败更多、重试更…- 0
- 0
-
我用 Redis 做分布式锁防止任务被重复处理,结果先是一个实例崩了导致所有任务卡死,后来又出现同一个任务被两个实例同时处理,我对着分布式锁这几个致命实现细节排查了大半天的复盘
一个让我对分布式锁看着简单实则处处是坑彻底敬畏的架构坑,它教会我用 Redis 加把锁这件听起来一行代码搞定的事要真正正确实现需要考虑一连串容易被忽略的细节,漏掉任何一个锁就会在某种场景失效——要么死锁卡死所有人要么形同虚设根本没锁住。多实例下要保证同一时刻只有一个实例处理某任务,我用 Redis 分布式锁逐步踩坑:版本1 SETNX+DEL 没过期时间,持锁实例崩了锁永不释放全卡死(死锁);版本…- 2
- 0
-
用户只点了一次提交,因为网络超时客户端自动重试,结果同一笔订单被下了两次、款也扣了两次,我对着接口没做幂等设计这个坑排查大半天的复盘
一个让我对分布式与网络环境下的不确定性彻底敬畏的架构坑,后怕在出问题的不是某段写错的逻辑,而是一个我压根没考虑过的场景:同一个请求被处理了不止一次,而这在真实网络世界里是必然。用户投诉只下了一单却被扣两次款收到两份货,查日志确有两条几乎同时、内容完全一样的下单记录。下单接口逻辑朴实:扣库存、扣款、创建订单、发货。问题在于:用户点提交,请求到服务器其实已成功处理,但响应网络包回来路上超时丢失,客户端…- 0
- 0
-
一条扣款消息被消费了两次、用户被重复扣了钱,我查遍代码逻辑都没错、消息也确实只发了一条,我对着幂等性缺失和消息重投排查了大半天的复盘
半夜被电话叫醒的线上事故:有用户一笔订单被扣了两次钱。翻遍扣款逻辑没有任何会扣两次的分支,查消息队列确认上游那条扣款消息确实只发了一条。一条消息、一段没错的代码,怎么就扣了两次?排查大半天才理解分布式系统最易被忽略却最致命的设计缺失——幂等性,以及 MQ "至少投递一次"这个我从没认真对待的特性。事故链条是:消费者成功扣款,但 ACK 确认时网络抖动/重启导致 ACK 丢失,M…- 0
- 0
-
下游只是发布时抖了一下,我的服务却因为疯狂重试把它彻底打死、还让它久久无法恢复,我对着重试风暴和指数退避加抖动排查了大半天的复盘
一次本该轻描淡写的小故障:依赖的下游因发布短暂抖动几秒,本来加了重试就该平稳扛过。我也确实加了重试——失败就重试最多 3 次,以为很稳健。结果这"几秒小抖动"被重试放大成持续十几分钟的大故障:下游不但没恢复反而被打得更死,抖动结束后还久久缓不过来。百思不得其解:重试不是为了提高成功率吗怎么把下游搞死了?排查大半天才理解"重试风暴"这个反直觉陷阱:我的立即重试…- 0
- 0
-
我的下单接口偶尔会给同一个用户生成两笔一模一样的订单、甚至重复扣款,我对着这些诡异的重复数据排查了大半天才真正理解幂等性的复盘
我的下单接口偶尔生成两笔几乎一模一样的订单、甚至同一笔消费扣两次款,两条订单除订单号外字段全同、时间差几百毫秒像被复制。我一开始以为是用户手抖点两次,排查日志才懂:重复大多不是点两次,而是"重试"——服务端处理成功了但返回响应超时,前端没收到成功就自动重试;调下游支付成功了但响应超时,本服务以为失败就重试;走 MQ 的 at-least-once 同一消息被消费多次。本质是网络…- 0
- 0
-
我的下单接口被同一个请求重复调用,结果生成了两笔一模一样的订单,我一开始以为是前端 bug,最后才明白重试在分布式里根本无法避免、而我没做幂等的深度复盘
我的下单接口,用户点一次就该下一单,可线上时不时冒出重复订单:同样的商品金额生成了两笔三笔。我第一反应甩锅前端"重复调用了",让前端加防抖,可问题依然。复盘完整链路才痛悟:根子不在前端,而在我没做幂等。分布式里重复请求根本无法避免——网络超时重试(后端其实成功了只是响应没回来)、用户重复点、网关自动重试、MQ 至少一次投递,而后端根本分不清"新订单"还是&q…- 0
- 0
-
用户下了单没收到短信、买了东西积分没加,订单明明下单成功后续处理却像从来没发生过一样凭空消失:消息队列消息丢失的端到端可靠性避坑复盘
这是一个东西凭空消失的事故而且消失得无声无息直到用户投诉才暴露。我们用消息队列做订单的异步后续处理,用户下完单主流程往 MQ 里发一条消息然后下游的消费者收到消息去做那些不那么紧急的后续事发短信通知给用户加积分同步给其它系统。这套用 MQ 解耦异步的架构很常见也很优雅,可上线一段时间后陆续有用户反馈:我下了单怎么没收到短信?我买了东西积分怎么没加?而去查订单本身是好好的下单成功了,可那些后续处理有…- 3
- 0
-
用户刚保存提示成功一刷新却还是旧内容、下单成功转头查这单却偶发报订单不存在:读写分离架构下主从复制延迟读到旧数据的踩坑复盘
这个 bug 的用户反馈听起来特别像在见鬼:用户明明刚刚保存了修改、系统也提示保存成功了,可页面一刷新显示的还是修改前的旧内容,好像他的修改凭空消失了,于是用户狐疑地又改了一遍又保存刷新,这次有时对了有时还是旧的时灵时不灵。更要命的是另一处:我们的下单流程写入订单成功后紧接着的一个步骤要去查这条刚下的订单,结果偶发性地报订单不存在,一条我们明明刚刚亲手写进数据库的订单转头就查不到了。这两个见鬼的现…- 0
- 0
-
重试把下游打死了:重试风暴避坑复盘
这是一次好心办坏事的典型事故,也是我对重试这个看似无害的机制彻底改观的一次。起因很小:我们依赖的一个下游服务某天出现了短暂抖动,有那么几秒钟变慢了少量请求超时了,这本来是件小事下游抖一下缓一缓通常几秒就自己恢复了。可那天它不仅没恢复反而被彻底打挂了一垮就是好久,连带把我们整个服务也拖垮了。事后复盘真凶让我大跌眼镜——把下游打死的不是别人,正是我们自己为了提高成功率而精心设计的失败自动重试机制。这就…- 2
- 0
-
对账邮件发了三遍:多实例定时任务避坑复盘
那天上午客服转来一条用户投诉让我心里咯噔一下:你们的对账邮件我今天早上一口气收到了三封一模一样,是不是系统出 bug 了?我第一反应是邮件服务重试了?可一查发邮件的代码确确实实只被成功调用了三次,每次都正大光明地发了一封,不是重试是实打实地执行了三遍。而这个发对账邮件的任务是一个每天凌晨定时跑一次的定时任务,逻辑里清清楚楚写着每个用户发一封,怎么会发三封?真相藏在一个我们为了高可用而做的本身完全正…- 0
- 0
-
从粗放架构把用户商品订单库存支付营销所有业务不加边界地堆进同一个一百多万行的巨石单体进程任其强耦合成谁也理不清的乱麻改一个边角功能也要重新打包停服部署整个单体一个不相关模块的内存泄漏 OOM 就把整个进程拖垮导致全站一起宕机陪葬 + 拆开后把对端服务的 IP 端口硬编码写死在配置里实例扩容换机宕机就得满世界改配置重启对端进程崩了 IP 还在照样把请求往死实例上送负载也没法均衡 + 各微服务直接把接口暴露给客户端直连鉴权限流日志跨域这些横切逻辑在每个服务重复写一套既散乱又不一致一处有漏洞就是全系统破口后端结构全暴露给客户端 + 服务间清一色同步阻塞 RPC 调用订单要死等库存积分通知营销一长串下游依次返回可用性被乘法级稀释一个发短信服务抖动竟拖垮核心下单洪峰原封不动砸到每个下游 + 按领域拆库后本地事务跨不了多个独立库订单已落库但扣库存失败数据停在订单有了库存没扣的永久错误中间态还撤不回来 + 服务间无超时无熔断的裸调一个下游变慢就把上游线程池占满耗尽上游自己也挂故障顺调用链一级级反向传染雪崩拖垮大半个系统 + 有副作用的接口不做幂等来一次执行一次网络超时调用方重试同一笔支付被重复扣两三次钱同一个单生成好几个重复订单 + 请求跨网关订单用户库存支付好几个进程几台机器日志散落各处无任何关联线索串联断成谁也不认识谁的碎片排查跨服务慢请求只能逐台机器大海捞针拼凑数小时 → 2026 现代微服务架构 按 DDD 限界上下文沿领域边界拆成独立部署独立库独立进程故障隔离的微服务 + 注册中心自注册心跳按服务名动态发现健康实例 + 统一 API 网关收口横切逻辑写一处屏蔽内部结构 + 区分强一致与最终一致非核心下游改消息事件驱动异步消费解耦削峰填谷 + Saga 为每步配补偿操作失败反向回滚保最终一致 + 熔断器监控失败率慢调用超阈值跳闸快速拒绝走降级兜底故障就地隔离 + 全局幂等键加去重表唯一约束保证重复请求只执行一次副作用 + 全链路 TraceID 入口生成沿途透传把跨服务足迹串成完整链路分钟级定位 87 天战役复盘:47 套工程修法 + 7 个 P0 复盘 + 6 条工程哲学
9 人的架构团队 87 天把一套支撑公司整条电商交易主链路、五年里从几万行野蛮生长成一百多万行、几十个开发同时往里提交谁也说不清全貌的巨石单体——用户商品订单库存支付营销所有业务全都长在同一个代码仓库编译成同一个部署包跑在同一个进程里模块之间直接 import 一个类调一个方法进程内强耦合缠成一团乱麻、任何一点改动都要全体陪葬改营销一个边角的活动规则也得把整个百万行单体重新编译打包停服部署几十个开…- 0
- 0
-
从粗放跨网络调用天真当成调一下拿到结果不设超时无脑重试没熔断不限流不隔离 + 不设超时或设几十秒慢下游把调用线程一个个挂死耗尽线程池调用方自己也垮再沿调用链层层传导冲垮整个核心链路雪崩 + 失败就立即原地无脑固定次数猛重试给过载下游火上浇油 N 客户端乘 M 重试瞬间放大数倍把下游彻底打死死亡螺旋还对扣款下单非幂等操作重试导致重复扣款下单 + 下游已经挂了还一根筋拼命猛打无效请求堆积线程全卡在死路上白耗资源还堵死下游恢复 + 对入口流量来者不拒突发洪峰直接把服务自身资源榨干压垮容量内请求也一起玉石俱焚 + 所有下游调用共用一个线程池连接池一个无关紧要的边缘慢下游就把公共池占满连核心订单支付调用也申请不到线程全线瘫痪 + 下游一挂调用方直接把故障原样上抛一个推荐挂掉整个详情页打不开用户连看商品下单都做不了被次要功能绑架核心 + 客户端无脑轮询所有后端不感知健康把请求往挂掉卡死的实例上送间歇性报错忙的更忙 + 网络调用是黑盒出事只能逐个翻日志加 tcpdump 抓包连蒙带猜耗时数小时抓不到是哪一跳慢 → 2026 现代服务间通信韧性工程 每个调用设合理超时加全链路 deadline 剩余预算传播 + 指数退避加抖动加只重试幂等加重试预算绝不放大故障 + 熔断器失败率超阈值快速失败给下游喘息给自己止血加半开试探 + 令牌桶漏桶限流超容量快速拒绝保住核心容量 + 舱壁隔离每个下游独立线程池连接池故障关在单个舱室 + 降级 fallback 下游不可用返回兜底数据保住主流程 + 健康检查加 P2C 最少连接加异常实例自动摘除 + 每跳成功率延迟熔断状态指标加分布式链路追踪 TraceID 串起整条链路 87 天战役复盘:47 套工程修法 + 7 个 P0 复盘 + 6 条工程哲学
9 人的服务治理与中间件团队 87 天把一套由上百个微服务彼此通过网络调用编织而成、五年里服务从十几个长到上百个调用关系织成一张谁也理不清的大网、却一直停留在调用一下拿到结果天真阶段不设超时无脑重试没熔断不限流不隔离的庞大系统——绝大多数地方调用下游压根不设超时或随手填个几十秒形同虚设慢下游一卡调用线程就永久阻塞傻等高并发下线程池被一个个挂死耗尽调用方自己也垮再沿调用链反向层层传导像多米诺骨牌把整…- 0
- 0
-
从古老单体巨石架构 所有业务模块全挤一个进程改一处就全量重新部署 + 模块间直接函数调用编译期强耦合牵一发动全身 + 单库单表所有数据全挤一个库改个表结构全线停机 + 服务间同步阻塞调用一个慢全链路雪崩 + 分布式事务靠 2PC 两阶段提交锁死性能 + 服务地址 IP 端口硬编码换台机器改一堆 + 配置散落硬编码改配置要重新打包发布 + 无 API 网关前端直连各后端认证限流各搞各的 + 系统集成靠共享数据库互相读写表耦合死 + 一次发布全量上线一个模块的 bug 拖垮整个系统 → 2026 现代微服务架构 微服务按业务域拆分独立部署独立伸缩 + DDD 领域驱动设计划分服务边界 + 服务间 gRPC/REST 契约通信 + database per service 每服务独享数据库 + Kafka 异步消息队列解耦削峰 + 事件驱动架构 EDA 发布订阅 + Saga 分布式事务最终一致性 + CQRS 读写分离 + 事件溯源 + 服务注册发现 + Istio 服务网格 + API 网关统一入口 + 配置中心动态刷新 + 绞杀者模式渐进迁移 87 天战役复盘:47 套工程修法 + 7 个 P0 复盘 + 6 条工程哲学
12 位架构与平台工程师 87 天把一套跑了五年的粗放单体巨石架构——订单库存支付用户几十个业务模块全挤在一个进程一个代码库一个数据库、模块间直接 import 互调编译期死死耦合改支付一个方法可能在订单意外炸、一个模块内存泄漏拖垮整个进程、想给大促压力最大的订单单独扩容却只能把整个巨石一起复制白烧资源、所有数据挤在一个库各模块随手跨表 join 互读互写共享库把所有模块焊死改张表全线停机、服务间…- 0
- 0
-
Redis 7.2 Cluster 12 节点扩容到 24 节点期间 P99 从 2.4ms 飙到 1.8 秒的 3 天复盘:大键 MIGRATE 阻塞 + MOVED redirect 风暴 + 客户端 slot 缓存雪崩三重叠加 + 11 条 Cluster 运维纪律
我们一个 Redis 7.2 Cluster 用户会话存储,12 节点扩容到 24 节点,在线 reshard 4 小时窗口里 P99 从 2.4ms 飙到 1.8 秒,应用层 50% 请求 timeout,47 个业务工单。3 天复盘找到三重根因:user:5000:big_session 单 key 12MB MIGRATE 阻塞主线程 200ms、Lettuce/ioredis MOVED …- 0
- 0
-
定时任务可靠性完全指南:从一次"任务跑成三份、还挂了一周没人知道"看懂防重叠、多实例单跑与可观测
2023 年我做一个后端服务有一堆需要定时跑的活儿每天凌晨生成报表每小时同步一次外部数据每隔几分钟清理过期数据。定时任务这件事我压根没多想。第一版我做得很省事定时任务不就是写个 cron 表达式到点了调一下那个函数用 APScheduler 之类的库挂一个 scheduled_job 函数体里该干嘛干嘛。本地开发时真不错我把触发间隔调短到一分钟盯着日志到点函数就跑跑完就停准得很。我心里很踏实定时任…- 2
- 0
-
一致性哈希完全指南:从一次"缓存集群加了一台机器、命中率瞬间归零"看懂分布式分片
2020 年我做一个分布式缓存。业务的读压力越来越大单台 Redis 扛不住了我决定加机器上 4 台 Redis 把缓存数据分散到这 4 台上。要解决的核心问题只有一个一个 key 进来我怎么决定它该存到该去哪一台机器上读。第一版我做得很直接把 key 算个哈希值对机器数取模算出 0 1 2 3 就去对应那台。本地一测很顺几百万个 key 均匀地散在 4 台机器上每台四分之一读写都飞快缓存命中率稳…- 0
- 0
-
消息队列完全指南:从一次"异步下单后积分没加、还重复扣了款"看懂可靠消息投递
2023 年我做一个电商的下单系统。下单成功后要做一连串事发短信通知给用户加积分通知仓库发货更新销量统计。第一版我做得很直接在下单接口里一件接一件同步地调结果接口慢得感人。我很快想到用消息队列下单成功后只往 MQ 里发一条订单已创建的消息就立刻返回后面那些活交给消费者异步处理接口快得飞起。我心里很踏实消息发出去了后面的事自然有人处理。可上线之后客服的投诉一条接一条第一类用户明明下单成功了积分却没加…- 2
- 0
-
消息队列完全指南:从一次库存扣三次的事故看懂丢失、重复、顺序怎么治
2023 年我维护一个电商订单系统,用消息队列把下单后的扣库存/加积分/发短信改成异步——订单落库后发一条"订单已创建"消息交给各消费者处理。某次大促运营找来说爆款商品库存对不上:系统显示卖 1200 件实际出库只有 800 多,库存被扣多了。拉扣库存消费者日志顺着一个订单号查,愣住了:同一个订单的"扣库存"消息被消费了三次。我第一反应是"MQ 出…- 2
- 0
-
单表两亿行扛不住了:一次分库分表的复盘
orders 单表两亿行,加索引 DDL 卡几小时,单机磁盘连接数全到顶。分库分表是最后手段,先归档争取喘息。几周做完:垂直拆 vs 水平拆、选分片键 buyer_id+订单号基因法、hash 取模一次给足分片数、攻克分布式 ID 与跨片分页、双写灰度迁移全程对账。- 0
- 0
分布式
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!
























