-
我给服务做了配置热更新不重启就能改限流阈值这些参数、本以为很丝滑,可有一次我同时改了限流的阈值和时间窗口两个相关参数推下去、那一瞬间线上限流就乱套了有请求按新阈值配旧窗口的奇怪组合被误杀,排查很久才搞懂我的热更新是一个字段一个字段改的并发请求正好读到了一半新一半旧的中间态的深度复盘
我给服务接了配置中心做了热更新、不重启就能让新配置生效,平时改单个参数很丝滑。直到一次同时改了限流的两个相关参数——阈值和时间窗口长度,推送上线那一瞬间:配置生效的那一两秒内限流突然异常、有些本该放行的被误杀 429 有些本该拦的又放过、像是用了新阈值加旧窗口或旧阈值加新窗口这种从没配过的奇怪组合在限流(而新配旧配单独都合理)、过一两秒就自己好了、改单个参数从没出过这事。这几条指向我热更新代码里的…- 2
- 0
-
我给一个上线已久的服务改了下消息格式把一个字段重命名顺手就发版了、自测和预发都好好的,可滚动发布刚推到一半生产就开始零星报错有些消息处理失败有些又正常、等全部实例滚完反而又恢复了,排查很久才反应过来滚动发布的那几分钟里新旧两个版本是同时在线的旧实例根本不认识新字段的深度复盘
我维护一个跑了很久的服务、通过消息队列和另一个消费方协作,这次做了个看起来无伤大雅的改动:把消息体里一个字段从 userName 改名成 username 统一命名风格,生产者消费者代码都改了,本地自测预发联调全正常就走正常流程滚动发布上线。结果发布过程中监控抽风:刚开始推新版本一切正常、等滚动发布推进到一半左右消费方开始零星报错(取不到用户名字段 null)、有的消息失败有的又好好的成功失败夹杂…- 2
- 0
-
我把几个服务实例缩容下线了、本以为流量自然就不会再来,可接下来好几十秒里调用方还在大量报连接被拒绝、请求纷纷失败,我盯着监控纳闷那些实例明明已经停了,最后才想明白实例没了是一回事调用方什么时候知道它没了是另一回事这中间隔着一段谁也绕不开的传播延迟的深度复盘
我的服务部署了多个实例、注册在服务注册中心、调用方通过服务发现拿到实例列表再负载均衡分发请求。某次缩容我把其中几个实例直接停掉,想当然以为实例一停就从可用列表没了、流量自然只去剩下的健康实例。可现实是停掉后好几十秒里调用方持续报错——大量 connection refused、超时、成功率掉一截才慢慢恢复。我确认那些实例真停了却百思不得其解,查调用方日志发现它请求的目标 IP 正是已下线实例。直到…- 0
- 0
-
我给一批缓存数据统一设了一小时过期、平时缓存命中率高得很数据库压力很小,可每隔整整一小时数据库就会突然被海量请求瞬间打垮、CPU 飙满响应超时,排查很久才惊觉那批缓存是同一时刻批量写进去的、于是又在同一时刻集体失效把流量齐刷刷地全砸向了数据库的深度复盘
我的系统在缓存里存了一大批热点数据(商品信息、配置项),为了定期刷新给每条都设了 TTL=1 小时,平时跑得非常好:绝大多数请求命中缓存根本不碰数据库、DB 的 QPS 低得可怜监控一片祥和。可诡异的事周期性发生:每隔大约一小时数据库就突然遭遇一波海量查询、QPS 瞬间冲到平时几十倍、CPU 打满连接池占爆大量超时,持续几秒到十几秒恢复、下个整点再来一次。我怀疑整点跑批(没有)、怀疑有人整点刷接口…- 0
- 0
-
我给接口加了限流、限定每分钟最多 600 次以为稳了,大促时下游服务还是被瞬间打爆雪崩,我反复确认限流配置数字没错、监控里平均 QPS 也没超百思不得其解,最后才发现是我用的固定窗口计数器在每分钟切换那一瞬间放进了两倍流量的深度复盘
我的服务前面挡着一层限流:统计每分钟进来多少请求、超过 600 个就拒绝、下一分钟清零重数,我对它很放心。可大促当晚下游连接池瞬间被占满、超时、连锁雪崩,而限流明明开着。我盯监控,每分钟请求量几乎都贴着 600 的线没哪分钟超过,拒绝计数也在涨说明它确实在拦,可下游就是被打爆了。我怀疑下游容量缩水、怀疑配置被改大,都没有。直到把被打爆那一刻精确到秒的请求时间戳拉出来按秒画图才倒吸凉气:某一分钟最后…- 0
- 0
-
我的下单接口偶尔会给同一个用户重复下两笔一模一样的单、甚至重复扣款,可我代码里明明每次只下一单,排查半天才明白是客户端超时重试、用户手抖多点了几下,让同一个请求被发了好几次、而我的接口压根没防着重复的深度复盘
我有个下单接口:接到请求就创建订单、扣一次款,逻辑清清楚楚一次请求一个订单。我自己测试点一下下一单完美无缺。可上线后客服陆续投诉:有用户只下了一单,系统却给他创建了两三笔一模一样的订单、重复扣了好几次款。我翻日志发现重复订单都来自短时间内几乎同时到达、内容完全相同的多个请求。我以为是并发 bug、循环写错,检查下单逻辑都没问题。顺着重复请求往上游追才恍然:问题不在接口处理一次请求的逻辑,而在同一个…- 0
- 0
-
我把一个下单操作拆成了先调库存服务扣库存、再调订单服务建订单,本地测试一路绿灯,可上线后偶尔出现库存扣了、订单却没建成,钱货两空、数据对不上,排查半天才明白跨服务的操作根本没有我以为的那种原子性的深度复盘
我做了个下单流程涉及两个独立微服务:库存服务和订单服务,代码很直白——第一步调库存服务扣库存,第二步调订单服务建订单。本地测试两步都顺利,我便觉得天衣无缝。可上线后客服陆续收到投诉:有用户下单失败可库存却被扣了;对账也发现库存扣减记录和实际订单数对不上,有批库存凭空少了却找不到对应订单。翻日志真相浮现:这些异常都是第一步扣库存成功了、第二步建订单失败了(订单服务超时/宕机/网络抖),第一步已实实在…- 0
- 0
-
我的核心下单服务好端端的突然大面积超时崩了,排查半天发现罪魁祸首竟是一个无关紧要的猜你喜欢推荐功能——它依赖的服务挂了,而我没做熔断降级,卡住的调用把整个服务的线程池占满、连下单都瘫了的深度复盘
我维护一个电商核心服务,有下单、查订单这些命脉功能,也顺带集成了一个猜你喜欢推荐——调一个独立推荐服务展示几个推荐商品,我一直觉得它挂了顶多少几个推荐位、无关痛痒。可那天监控突然炸了:整个核心服务大面积超时几乎瘫痪、下单成功率断崖下跌。我以为是数据库或下单逻辑出问题,翻遍下单链路都正常,直到打出线程堆栈才目瞪口呆:服务里几乎所有工作线程都卡在调那个推荐服务上干等着!原来推荐服务故障响应极慢,而我调…- 0
- 0
-
我用雪花算法生成分布式订单 ID,跑了大半年一直好好的,某天凌晨服务器自动校了一次时、把时钟往回拨了几毫秒,雪花算法当场抛异常拒绝生成 ID、订单全下不了的深度复盘
我用雪花算法(Snowflake)生成分布式唯一订单 ID(靠毫秒时间戳+机器ID+序列号拼出全局唯一且大致递增的 ID),跑了大半年稳得很。可某天凌晨突发:一段时间内所有下单都失败,日志全是雪花算法抛的 Clock moved backwards 时钟回拨异常,几分钟后又自己恢复。排查发现那台服务器凌晨做了一次 NTP 自动校时、把系统时钟往回拨了几毫秒,而雪花算法检测到当前时间小于上次生成 I…- 0
- 0
-
我们追求微服务把一个本来内聚的业务拆成了十几个小服务,本想解耦独立部署,结果一个下单流程要串着调八个服务、链路又长又慢、改一个小需求要协调好几个服务一起发版、出了问题谁也说不清的深度复盘
当时团队觉得微服务是趋势、拆得越细越解耦越灵活,就把一个本来还算内聚的业务系统拆成了十几个微服务(用户、订单、库存、价格、优惠券、积分、通知、风控……)。拆完上线问题接踵而至:一个下单流程要串行调用七八个服务、链路又长又慢、任一服务抖动整个下单就受影响;改个下单送积分的小需求要同时改好几个服务、协调它们一起发版联调;数据一致性成了噩梦、分布式事务焦头烂额;出问题一个请求跨好几个服务谁也说不清。复盘…- 2
- 0
-
我用消息队列解耦订单处理,以为一条消息只会被消费一次,结果某条扣库存的消息被重复消费了两次,库存莫名其妙被多扣了一份:一次没为消息重复投递做幂等、误把至少一次当成恰好一次的深度复盘
我用消息队列解耦订单流程:订单服务下单发消息,库存服务消费消息扣库存。我想当然地以为一条消息只会被消费一次,消费逻辑写得很直白:收到就扣。线上跑了一阵对账发现少量订单库存被扣了两次——只买 1 件却少了 2 件。翻日志才发现:那几条消息确实被同一个 messageId 消费了两遍。复盘 MQ 投递语义才恍然大悟:绝大多数消息队列默认是至少一次(at-least-once)投递,不是恰好一次(exa…- 0
- 0
-
一个被高频访问的热点缓存恰好过期的那一瞬间,几千个请求同时扑向数据库去重建它,瞬间把数据库打垮了:一次缓存击穿、热点 key 过期空窗的深度复盘
我有个被高频访问的热点数据放在缓存里、设了 5 分钟过期,平时读缓存命中一切顺滑。可某次监控突然报警数据库 CPU/连接数瞬间飙满、差点雪崩,恰好发生在那个热点缓存过期的那一刻。复盘那一瞬间才明白这是缓存击穿:那个 key 被每秒几千请求高频访问,当它到点过期从缓存消失的瞬间,几千个并发请求同时发现未命中、几乎同时全部扑向数据库去查数据重建缓存,本该由缓存挡住的几千 QPS 在这一瞬间全砸到数据库…- 0
- 0
-
我用 Redis 加了分布式锁保护临界区,以为万无一失,结果偶发两个进程同时进了临界区、一个进程还把别人的锁给删了:一次分布式锁实现陷阱的深度复盘
我有段临界区代码用 Redis 加了分布式锁保护:SET lock NX EX 30 抢锁、处理完 DEL 释放,以为万无一失。可线上偶发两个进程同时进入临界区的数据错乱,有时还有一个进程把另一个进程正持有的锁删了。推演时序才看明白这锁有两个致命漏洞:漏洞一,锁 EX 30 过期了但业务还没跑完,锁自动释放、B 抢到、A 和 B 同时在临界区;漏洞二,释放时直接 DEL 没校验是不是自己的锁,A …- 0
- 0
-
用户明明改了资料、刷新却还是旧的,排查发现是我更新数据库后顺手更新缓存在高并发下把旧值写回了缓存:一次缓存与数据库双写一致性、Cache-Aside 该删缓存而非更新缓存的深度复盘
我们的用户资料服务为扛读量加了 Redis 缓存,读走缓存未命中查库回填,写用我自以为周到的先更新数据库再顺手更新缓存。功能测着没问题,线上却偶发:用户改了资料、缓存却长期是旧值,刷不新直到过期才好。在并发场景下推演才看明白:更新库和更新缓存两步非原子,两个并发写请求 A、B 都先更库再更缓存,DB 最终是 B 的新值(对),但更新缓存时因线程调度 B 先写、A 后写,缓存被覆盖回 A 的旧值——…- 0
- 0
-
我用 Redis 做分布式锁防止任务被重复处理,结果先是一个实例崩了导致所有任务卡死,后来又出现同一个任务被两个实例同时处理,我对着分布式锁这几个致命实现细节排查了大半天的复盘
一个让我对分布式锁看着简单实则处处是坑彻底敬畏的架构坑,它教会我用 Redis 加把锁这件听起来一行代码搞定的事要真正正确实现需要考虑一连串容易被忽略的细节,漏掉任何一个锁就会在某种场景失效——要么死锁卡死所有人要么形同虚设根本没锁住。多实例下要保证同一时刻只有一个实例处理某任务,我用 Redis 分布式锁逐步踩坑:版本1 SETNX+DEL 没过期时间,持锁实例崩了锁永不释放全卡死(死锁);版本…- 2
- 0
-
一个超热点的商品缓存在过期那一瞬间,成千上万的请求同时涌向数据库去重建它,把 DB 瞬间打垮,我对着缓存击穿这个热点 key 过期引发的惊群效应排查了大半天的复盘
一个让我对缓存不是万能挡箭牌彻底清醒的架构坑,诡异在平时缓存把 DB 保护得很好负载很低,可某个特定瞬间 DB 会突然遭受排山倒海的并发冲击而崩溃——而这瞬间恰是某个最热门的缓存刚好过期那一刻。系统用 Redis 缓存商品详情设 1 小时过期,DB 监控却毫无规律间歇性出现瞬时高负载连接打满。代码是标准的读缓存没有就查 DB 回填。隐患在并发:一个爆款商品每秒上万请求,缓存过期那一瞬间这上万并发几…- 0
- 0
-
用户只点了一次提交,因为网络超时客户端自动重试,结果同一笔订单被下了两次、款也扣了两次,我对着接口没做幂等设计这个坑排查大半天的复盘
一个让我对分布式与网络环境下的不确定性彻底敬畏的架构坑,后怕在出问题的不是某段写错的逻辑,而是一个我压根没考虑过的场景:同一个请求被处理了不止一次,而这在真实网络世界里是必然。用户投诉只下了一单却被扣两次款收到两份货,查日志确有两条几乎同时、内容完全一样的下单记录。下单接口逻辑朴实:扣库存、扣款、创建订单、发货。问题在于:用户点提交,请求到服务器其实已成功处理,但响应网络包回来路上超时丢失,客户端…- 0
- 0
-
我用 Redis 加了分布式锁防并发,结果偶尔还是有两个节点同时拿到锁、把临界区并发执行了,我对着这把"形同虚设"的锁排查了大半天的复盘
我用 Redis 的 SETNX 加锁、设过期时间防死锁、用完 DEL 释放,实现了分布式锁防并发,结果临界区偶尔还是被两个节点同时执行、锁形同虚设,还极其偶发难复现。把时序画出来才懂两个致命问题:① 业务执行时间超过了锁的过期时间,锁自动到期释放、另一个节点趁机拿到锁,于是两节点同时持锁;② 释放锁直接 DEL 没校验"是不是自己的锁",A 超时后 B 拿到锁,A 执行完却把…- 0
- 0
-
我给热点数据加了缓存提速,结果用户改完资料刷新还是看到旧的、甚至并发改一下缓存就和数据库长期对不上,我对着这个缓存一致性问题排查了大半天的复盘
我给热点数据加了 Redis 缓存提速,结果用户改完资料、提示保存成功了,刷新还是旧数据;并发下偶尔缓存和数据库长期对不上、怎么刷都不对,只能手动清缓存。我加了"更新数据库后也更新缓存"反而更乱。把并发读写画在时间轴上才懂:缓存和数据库是两个独立系统、更新无法原子完成,中间总有不一致窗口,并发下交错就出问题;而我犯的典型错误是选了"更新缓存"而非"…- 0
- 0
-
我的下单接口偶尔会给同一个用户生成两笔一模一样的订单、甚至重复扣款,我对着这些诡异的重复数据排查了大半天才真正理解幂等性的复盘
我的下单接口偶尔生成两笔几乎一模一样的订单、甚至同一笔消费扣两次款,两条订单除订单号外字段全同、时间差几百毫秒像被复制。我一开始以为是用户手抖点两次,排查日志才懂:重复大多不是点两次,而是"重试"——服务端处理成功了但返回响应超时,前端没收到成功就自动重试;调下游支付成功了但响应超时,本服务以为失败就重试;走 MQ 的 at-least-once 同一消息被消费多次。本质是网络…- 0
- 0
-
我给热点数据加了缓存,本以为能稳稳扛住流量、高枕无忧,结果缓存一过期,成千上万的请求在那一瞬间全砸到了数据库、把它直接压垮的深度复盘
我给热点数据加了 Redis 缓存,数据库压力一下就下来了,很满意。可某天高峰,数据库突然被打挂。不是有缓存挡着吗?盯监控复盘才发现:数据库挂掉恰好在那个热点缓存"过期"的一瞬间——这是经典的缓存击穿。热点 key 过期那一刻缓存突然没了,而此时正有上万并发在访问它,它们同时未命中、同时涌向数据库,瞬间把库压垮;第一个请求还没回填好,后续继续砸库,恶性循环。我只享受了缓存命中时…- 0
- 0
-
我的下单接口被同一个请求重复调用,结果生成了两笔一模一样的订单,我一开始以为是前端 bug,最后才明白重试在分布式里根本无法避免、而我没做幂等的深度复盘
我的下单接口,用户点一次就该下一单,可线上时不时冒出重复订单:同样的商品金额生成了两笔三笔。我第一反应甩锅前端"重复调用了",让前端加防抖,可问题依然。复盘完整链路才痛悟:根子不在前端,而在我没做幂等。分布式里重复请求根本无法避免——网络超时重试(后端其实成功了只是响应没回来)、用户重复点、网关自动重试、MQ 至少一次投递,而后端根本分不清"新订单"还是&q…- 0
- 0
-
我刚写入数据库的数据,紧接着一查却说查不到,我一口咬定是事务没提交、对着事务代码排查了好几天,最后才发现是读写分离的主从延迟在作怪的深度复盘
我们为扛读流量做了读写分离:写走主库,读分摊到从库。可一个诡异 bug 折磨了我好几天——用户提交一条数据,代码先写库、紧接着立刻查它,结果那条刚写进去的数据竟然"查不到"、或查到旧值!而且时有时无,测试环境几乎不出,一到高峰就频繁冒。我一口咬定是事务没提交,查了好几天事务代码,最后才醒悟:写走主库、紧接着的读却走了从库,而主从复制是异步的、有复制延迟,数据还没同步到从库就被读…- 0
- 0
-
用户下了单没收到短信、买了东西积分没加,订单明明下单成功后续处理却像从来没发生过一样凭空消失:消息队列消息丢失的端到端可靠性避坑复盘
这是一个东西凭空消失的事故而且消失得无声无息直到用户投诉才暴露。我们用消息队列做订单的异步后续处理,用户下完单主流程往 MQ 里发一条消息然后下游的消费者收到消息去做那些不那么紧急的后续事发短信通知给用户加积分同步给其它系统。这套用 MQ 解耦异步的架构很常见也很优雅,可上线一段时间后陆续有用户反馈:我下了单怎么没收到短信?我买了东西积分怎么没加?而去查订单本身是好好的下单成功了,可那些后续处理有…- 3
- 0
架构
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!
























