架构实战:设计一个秒杀系统 —— 把前面学的全串起来
架构实战:设计一个秒杀系统 —— 把前面学的全串起来
秒杀是公认的后端压轴题:瞬时几十万人抢几百件货、库存绝对不能超卖、还混着一堆刷子——几乎把服务端的主要难点一次性全考了。这篇以秒杀为主线,把缓存、限流、消息队列、分布式锁这些零件如何在一个真实系统里拼到一起,完整设计一遍。
一、秒杀到底难在哪 —— 先看清这道题考什么
动手设计前,得先看清难点在哪,不然容易东补一块西补一块。秒杀的难,集中在四个点:
难点一:瞬时洪峰,量级极不均衡。 平时这系统可能就几百 QPS,活动开始那一秒,几十万甚至上百万请求一起砸进来抢几百上千件货。难的不是"流量大",而是这个高峰只持续几秒、却高得离谱——你不可能为这几秒常备几百台机器干等着(平时全闲着、纯烧钱)。
难点二:绝对不能超卖。 库存 100 件,卖出去 101 件就是事故——多出来那一单要么贴钱补货、要么取消订单挨投诉。超卖的根源是并发:成千上万个请求几乎同时来读库存、都看到"还剩 1 件"、于是都以为自己抢到了。这是典型的并发安全问题,也是秒杀最硬的一关。
难点三:大量刷子。 真正的人没你想得多,机器(脚本、刷子)却很多。有人写脚本抢、有人用代理 IP 批量刷、有人提前拿到接口绕过页面直接调。不防刷,公平性没了,真实用户抢不到,资源还全喂给了机器。
难点四:热点数据极端集中。 所有人盯着同一个商品、同一个库存 key。这正是《缓存架构》篇说的超热点 key(hotkey)——加再多缓存分片也分摊不掉,因为大家压的就是那一个 key。
一句话点破:秒杀的设计哲学,就一句——层层过滤,把流量像漏斗一样越漏越少。几十万请求进来,真正需要落到数据库去扣库存的,最后只该剩几百个(约等于库存量)。前面每一关,都是为了让漏斗的下一层轻一点。
下面就顺着这个漏斗,一关一关设计下去。每一关用的,基本都是前面某一篇讲过的手段——这篇做的事,就是把它们摆到正确的位置上。
二、第一关 · 扛住"读"洪峰 —— 让大部分人压根不碰后端
是什么。 秒杀页面被打开的次数,远多于真正点"抢"的次数——大量流量是反复刷新商详页、看倒计时的"读"。第一关的目标,就是让这些读请求尽量别进到后端业务系统里,在更靠外的地方就把它们消化掉。
为什么先打读。 因为读洪峰的量比写大得多,而且读是可以被缓存挡住的——同一个商品页,对一万个人长一个样,没必要让后端重复算一万遍。把读挡在外面,后端才有余力去处理真正金贵的"抢"。这一关直接复用《缓存架构》篇那条多级缓存纵深防线。
实际业务场景 + 怎么一步步设计。
第 1 步:页面静态化 + CDN。 秒杀商详页(商品图、标题、活动规则)在活动期间基本是不变的,那就别让它每次都由后端动态渲染。把页面静态化成一个 HTML,推到 CDN(《缓存架构》篇第一层)缓存到全国各地边缘节点。用户打开页面,就近从 CDN 取,请求根本到不了你的机房。这一步就能把绝大多数"看页面"的流量挡在机房之外。
第 2 步:商品详情走多级缓存。 页面里动态的那部分(比如实时的"已售/剩余"提示、用户自己的状态),才需要请求后端。这部分接口套上《缓存架构》篇的多级缓存:能在浏览器 HTTP 缓存命中的不回源,能在本地缓存(进程内)命中的不打 Redis,能在 Redis 命中的不碰数据库。尤其那个被所有人盯着的商品信息,正是超热点 key——按《缓存架构》篇的标准解法,把它提到每台应用机的本地缓存里,流量在本机内存就消化了,根本不去挤 Redis 的热点分片。
第 3 步:按钮置灰 + 答题错峰,从源头削平峰值。 这是秒杀特有的小心机:
- 倒计时按钮置灰:活动没开始,前端"抢购"按钮是灰的、点不动——让大家的点击分散在开始前的等待里,而不是全卡在零点同一瞬间爆发。
- 答题 / 滑块验证:点抢购前先答一道题或拖一下滑块。它一举两得——既把"瞬时一个点"的峰值摊平成几秒的小坡(每个人答题快慢不一),又顺手挡了一批不会答题的脚本(防刷,见第六关)。
业界怎么做。 这套"静态化 + CDN + 多级缓存 + 答题错峰"是电商大促的标准操作。静态资源一律上 CDN(阿里云 CDN、AWS CloudFront);动态接口的多级缓存用 Caffeine(本地)+ Redis(分布式);答题错峰则是各大平台秒杀里随处可见的设计——你以为是在防作弊,它同时也在帮服务端削平那个要命的瞬时尖峰。
注意事项。
- 静态页里别嵌死库存数字。 "还剩几件"这种实时数据,要用单独的异步接口去拉,别烤进静态 HTML——否则 CDN 上缓存的就是一个永远不变的假数字。
- 本地缓存只放能容忍短暂旧值的数据。 商品标题、规则可以;但真实库存绝不能只靠本地缓存判定(每台机器各存一份、还有 TTL 延迟),库存的权威判定要留到第四关。这点《缓存架构》篇反复强调过。
三、第二关 · 拦掉大部分流量 —— 多层限流,只放一小撮进去
是什么。 读洪峰被第一关挡掉后,剩下的是真心想"抢"的写请求。但这批量还是远超库存——100 件货,可能有 50 万人点了抢购。第二关的任务,是用《高并发三板斧》篇的限流,把这 50 万狠狠砍到只剩一小批,放进去争抢就够了。
为什么要在这儿就砍狠一点。 核心认知来自《高并发三板斧》篇那句:宁可干脆拒绝一部分,也别让所有请求一起死。库存就 100 件,真没必要让 50 万请求全涌到后面去扣库存——放进去 1 万个争抢这 100 件,体验上和放进去 50 万没区别(反正都是几百个抢到),但后端轻松了好几个数量级。挡得越靠前、越狠,后面每一层越省。
实际业务场景 + 怎么一步步设计。 限流要做成多层,从外到里一层层收窄:
第 1 层 · 网关限流。 在接入层网关(Nginx、APISIX、Kong)上配总闸——这个秒杀接口每秒最多放 N 个请求进后端,超了直接挡在门外、返回《高并发三板斧》篇说的 429 Too Many Requests + 友好提示("活动太火爆,稍后再试")。算法用《高并发三板斧》篇里最常用的令牌桶(允许一点突发,又有长期均值上限)。这是第一道、也是挡量最大的一道。
第 2 层 · 按用户 / IP 限流。 网关的总闸是"全局水位",还得防单个用户/单个 IP 疯狂刷。按维度细粒度限流:同一用户 1 秒内只准点 1 次、同一 IP 短时间内超过多少次就掐掉。多台机器要共享这个计数,就用《高并发三板斧》篇提到的分布式限流——Redis + Lua 脚本把"计数 + 判断"做成一个原子操作。这一层既限流也顺手防了刷(和第六关呼应)。
第 3 层 · 库存售罄,直接拒绝(最关键的一刀)。 这是秒杀限流的点睛之笔:在 Redis 里放一个"是否售罄"的标记,一旦库存被抢光,就把这个标记置上。之后所有请求进来,第一件事就是看这个标记——已售罄就立刻返回"抢光了",根本不往后走(不查库存、不排队、不下单)。
一句话点破:秒杀的库存只有几百件,意味着活动开始后一两秒,库存大概率就没了。剩下 99% 的请求,本质上都是来扑空的——与其让它们走完整条链路再发现没货,不如在最外面用一个"售罄标记"一刀全拒掉。这一刀,挡掉的往往是最大的一片流量。
业界怎么做。 多层限流是秒杀的骨架打法:网关层(Nginx/APISIX)扛总量,应用层用 Sentinel(《高并发三板斧》篇提过,限流熔断一套都能做)做精细规则,分布式计数靠 Redis+Lua。"售罄标记前置"更是几乎所有秒杀系统的标配——它把"判断有没有货"这件最高频的事,用一个内存里的布尔值就解决了。
注意事项。
- 阈值定多少是门玄学,得压测 + 灰度调。 《高并发三板斧》篇说过,定高了形同虚设、定低了误伤真实用户,只能先压测出容量、留余量当阈值,再看线上表现慢慢调。
- 被限流的反馈别太粗暴。 返回 429 时给个友好文案或排队页;前端拿到 429 别无脑立刻重试,否则等于把刚限住的压力又顶回来。
四、第三关 · 库存扣减不超卖 —— 这是整个秒杀的命门
是什么。 流量被砍到一小批后,真正的硬骨头来了:这一小批请求几乎同时要扣同一个库存,怎么保证扣减是并发安全的、绝不超卖。这一关,就是秒杀和普通系统最不一样、也最容易翻车的地方。
为什么不能直接打数据库扣。 先想最朴素的写法:每个请求都去数据库 查库存 → 判断够不够 → 扣减。两个致命问题:
- 扛不住。 就算限流后还有上万请求,全压到单个商品那一行上,数据库的行锁会让它们排成一条长队串行处理,几千 QPS 就能把库存所在的那个库拖垮——数据库是整条链路里最贵、最脆弱的一环(《缓存架构》篇反复说的"别让流量流到最后一层")。
- 会超卖。 如果图省事用"先查再扣"两步且没锁好,经典并发 bug 就来了:A、B 两个请求同时读到"剩 1 件",都判断"够",于是都扣——卖出去 2 件,超卖。
怎么一步步设计:Redis 预扣 + 原子操作。 业界的标准答案,是把库存的"实时争抢"这一步,从数据库挪到 Redis 上来做——这正好接上《缓存》篇埋的那个伏笔(那篇讲到"用 Redis 原子操作扛高并发扣减,属于秒杀架构的话题,这里不展开"——就是这儿了)。
第 1 步:活动前,把库存预热进 Redis。 活动开始前,把这场秒杀的库存数(比如 100)写进 Redis 的一个 key(《缓存架构》篇的缓存预热),作为这场争抢的"实时账本"。
第 2 步:用 Redis 的原子操作做"预扣"。 请求进来,在 Redis 里对库存做原子扣减——Redis 是单线程处理命令的,天然能保证"扣减"这个动作不会被两个请求同时插队。但秒杀的扣减不止"减 1",而是要先判断够不够、够才扣、不够就拒这一组动作要捆成一个原子整体,这就得请出《分布式锁》篇讲的 Lua 脚本:把"判断 + 扣减"写进一段 Lua,丢给 Redis 一次性原子执行,中间绝不会被别的请求插进来。扣成功了,这个请求才算抢到资格;Redis 库存减到 0,就置上第二关那个售罄标记,后面的请求直接被挡。
一句话点破:超卖的本质是"判断"和"扣减"两个动作中间被人插了队。解法不是"扣得更快",而是把"判断够不够 + 扣减"焊成一个谁也插不进来的原子操作——Redis 单线程 + Lua 脚本,正好提供了这个"焊"的能力。这就是为什么秒杀扣库存几乎都用 Redis + Lua,而不是裸打数据库。
第 3 步:为什么这里也常提"分布式锁"。 严格说,单个 key 的"判断+扣减"用 Lua 原子化就够了,未必非要显式加锁。但《分布式锁》篇的思路在更复杂的场景仍然用得上——比如要同时操作多个 key、或扣减逻辑复杂到一段 Lua 写不下时,就需要一把分布式锁(Redis 实现,业界常见 Redisson 这类库)把整段临界区锁住,保证同一时刻只有一个请求在改。记住那个判断:能用单条原子操作/Lua 解决的,就别上分布式锁(锁更重、更容易出问题);非得跨多个资源保证互斥时,才上锁。
第 4 步:最终怎么落到数据库。 Redis 预扣只是"实时争抢的账本",真正的订单和最终库存,还得落到数据库(Redis 万一宕机,数据不能就这么没了)。但这一步不在抢的那一瞬间同步做——抢到资格的请求,把"下单"这件事丢给下一关(MQ 异步),由数据库按自己的节奏慢慢扣减、落库。而且数据库这条最终扣减的 SQL,也要带上一道兜底防线:用 UPDATE ... SET stock = stock - 1 WHERE id = ? AND stock > 0 这种带条件的原子更新,靠 stock > 0 这个条件 + 数据库行锁,从最底层杜绝超卖——哪怕前面 Redis 那层万一算漏了,数据库这道也兜得住。
业界怎么做。 "Redis 预扣 + Lua 原子 + MQ 异步落库 + DB 带条件兜底"这套组合,基本就是主流秒杀扣库存的范式。Redis 抗住实时高并发争抢,数据库只接被削过峰的、不慌不忙的最终写入,各司其职。
注意事项。
- Redis 和数据库的库存最终要对得齐。 预扣在 Redis、落库在 DB,中间靠 MQ 衔接,要保证"Redis 扣了的,最终都在 DB 落上;没付款/超时的,库存要回滚还回去(Redis 和 DB 都要还)"。这块对账逻辑是秒杀容易出错的暗坑。
- Redis 这层别成单点。 库存账本全压在 Redis 上,它一挂全乱套——得上《缓存》篇说的 Redis 高可用(主从 + 哨兵 / 集群),这又接到第六关的兜底。
- 数据库的兜底条件别省。 哪怕你对 Redis 那层再有信心,DB 那句
WHERE stock > 0也要写上——多一道底裤,超卖这种事故经不起赌。
五、第四关 · 削峰下单 —— 抢到资格的,排队进 MQ 慢慢下单
是什么。 上一关抢到资格的请求,接下来要做的是真正下单(生成订单、扣最终库存、记录数据)——这是一组写数据库的重操作。第四关的设计,是不让这些下单请求在抢中的那一刻同步压到数据库,而是先塞进消息队列,让数据库按自己的速度慢慢消费。 这正是《消息队列》篇的削峰填谷。
为什么要异步削峰。 因为"抢到资格"是一瞬间的事,但"下单写库"是个慢动作。如果抢中的几百上千请求同步地一起写数据库,数据库又会在这一下被顶起来。《消息队列》篇那个比喻最贴切:MQ 当一个蓄水池——抢中的请求先快速把"下单消息"丢进队列(入队很轻、几乎不耗时),立刻给用户返回"正在排队/抢购中";数据库这边的消费者,按自己扛得住的速度一条条把订单落下去。把"一瞬间的高峰"摊平成"一小段时间的平稳写入"。
怎么一步步设计。
第 1 步:抢到资格 → 发一条下单消息进 MQ。 资格请求不直接写库,而是组装一条"用户 X 抢中商品 Y"的消息发进 MQ(Kafka / RocketMQ / RabbitMQ 都行,《消息队列》篇讲过选型),然后立刻返回。用户侧看到的是"排队中,请稍候"。
第 2 步:下单消费者按节奏落库。 MQ 后面挂着下单服务的消费者,匀速地取消息 → 扣数据库最终库存(就是第四关那句带 WHERE stock > 0 的原子 SQL)→ 生成订单 → 落库。数据库始终在安全水位跑,不会被秒杀那一下冲垮。
第 3 步:消费必须幂等。 这是《消息队列》篇反复强调的硬规矩:MQ 是 at-least-once(至少一次) 投递,同一条下单消息可能被投递多次(网络重试、ack 丢失都会触发)。下单逻辑必须幂等——同一个用户对同一场秒杀,重复消费也只能生成一个订单。做法就是《消息队列》篇那套:用唯一业务 id(用户+活动)+ 去重表(数据库唯一索引),重复的那条插入时唯一键冲突、直接挡掉。不做幂等,削峰削出一堆重复订单,等于白忙。
第 4 步:前端怎么知道结果。 既然下单变异步了,用户不能在原请求里同步拿到"抢到没"。两种业界常见做法:
- 轮询:前端拿到"排队中"后,隔一两秒去查一次"我的秒杀结果",查到"下单成功/失败"为止。简单,最常用。
- 服务端推送:用长连接(WebSocket / SSE)在订单落定后主动推结果给前端。体验更好,但要维护连接,复杂些。
业界怎么做。 "抢资格(Redis)→ 发消息(MQ)→ 异步下单(DB 消费)→ 前端轮询结果"是秒杀下单链路的经典三段式。它把秒杀拆成了快的归 Redis、慢的归数据库、中间用 MQ 缓冲,每一段都跑在自己舒服的水位上。
注意事项。
- 给用户的预期要管理好。 异步下单意味着"抢中"和"真正出单"之间有几秒延迟,前端文案要说清楚("排队中"而不是直接"成功"),别让用户以为卡了狂刷新。
- 超时与回滚要设计。 抢到资格但迟迟不付款的,要有超时机制把名额释放、库存还回去(Redis 和 DB 两边都还)——否则货被占着不付,真想买的人反而抢不到。
- MQ 也要防积压。 万一消费者跟不上,消息会在队列里堆积,要有监控和扩容消费者的预案(《消息队列》篇提的死信队列也是兜底之一)。
六、第五关 · 防刷与兜底 —— 守住公平,也守住"全挂"的底线
前面四关把"性能"和"超卖"解决了,但秒杀还有两件不能不管的事:别让机器把货全刷走(公平),以及万一某一环真挂了,整个系统别跟着全崩(高可用)。
① 防刷:别让脚本把真实用户挤出去
是什么 + 为什么。 秒杀利益大,天然招来脚本党:提前拿到接口直接调、用代理 IP 池绕过 IP 限流、机器人秒点。不防,真实用户根本抢不过机器,活动就失去意义了。防刷是一套组合拳,没有银弹:
- 限流维度防刷:第二关那套"按用户 / IP 限流"本身就是第一道防刷网,挡掉最粗暴的高频刷。
- 验证码 / 答题 / 滑块:第一关的答题错峰,同时也是防刷——机器不一定会答、滑块行为也能被识别,把一批脚本拦在门外。
- 隐藏 / 动态化秒杀接口:别让真实下单接口太容易被猜到、被提前调用。常见做法是抢购 URL 带一个活动开始后才下发的动态参数(令牌),没有它直接调接口无效,堵住"绕过页面直接打接口"。
- 风控:接入风控系统,综合设备指纹、账号历史行为、IP 画像等给请求打分,识别出机器/黄牛/异常账号直接拦截。风控是更上层的智能防线,前面几道是规则防线。
一句话点破:防刷防的不是"流量大",而是"流量不公平"——限流降的是总量,防刷拦的是那些不该占名额的请求。两者目标不同,要一起上。
② 兜底:守住"再坏也别全挂"的底线
秒杀链路上挂了 Redis、挂了 MQ、数据库被打慢……任何一环出问题,都不能让整个系统跟着雪崩。这就是《高可用》篇要解决的事,在秒杀里具体落成几条:
- 降级预案(《高并发三板斧》篇的"降级"):提前在配置中心(Nacos / Apollo)埋好降级开关。系统真扛不住时,一键弃车保帅——比如关掉商详页的评价、推荐这些非核心模块,把全部资源保给"抢 + 下单"这条命脉。涉及钱、库存、订单状态的核心环节绝不能乱降(降错了可能超卖,比不降更糟),这是《高并发三板斧》篇划的红线。
- 熔断(同篇):如果下单链路里某个下游(比如风控、支付)抽风变慢,用熔断快速失败,别让它顺着调用链把秒杀主流程一起拖死。
- 关键组件别留单点:Redis 上主从 + 哨兵 / 集群(《缓存》篇说的别让缓存成单点),数据库主从,应用多机部署,任何一台挂了系统还能跑——这是《高可用》篇消除单点、靠冗余换可用性的核心思路。
- 兜底文案:实在抢不到、或系统在保护性拒绝时,给用户一个体面的"手慢了,下次再来",而不是一个 500 错误页。优雅地失败,也是高可用的一部分。
注意事项。
- 降级开关要提前演练,《高并发三板斧》篇说得很重:预案不能等出事了现想,风平浪静时就得梳理好、演练过——秒杀那几秒,没有时间从头设计。
- 防刷和体验要平衡。 验证码太难、风控太严,会误伤真实用户;太松又防不住机器。这是个持续调的过程,没有一劳永逸的设定。
七、一张表:秒杀各环节 → 用了哪个架构手段 → 解决什么
把整条漏斗收进一张表——这也是这篇"串联"的全貌,每一行的"出处"都指回前面某一篇:
| 关卡 | 环节 | 用的架构手段 | 出处 | 解决什么 |
|---|---|---|---|---|
| 第一关 | 扛读洪峰 | 页面静态化 + CDN、多级缓存、答题错峰 | 《缓存架构》 | 让大部分"看页面"的读请求压根不进后端 |
| 第二关 | 拦写流量 | 网关限流 + 用户/IP 限流 + 售罄标记前置 | 《高并发三板斧》 | 把几十万写请求砍到一小撮,挡得越前越省 |
| 第三关 | 库存扣减 | Redis 原子预扣 + Lua 脚本 / 分布式锁,DB 带条件兜底 | 《分布式锁》《缓存》 | 高并发下绝不超卖,且不直接压垮数据库 |
| 第四关 | 削峰下单 | 抢到资格进 MQ,DB 异步消费 + 幂等 + 前端轮询 | 《消息队列》 | 把瞬时下单洪峰摊平,数据库按自己节奏写 |
| 第五关 · 防刷 | 守公平 | 限流 + 验证码/答题 + 动态接口 + 风控 | 《高并发三板斧》 | 拦掉脚本/黄牛,别让机器挤掉真实用户 |
| 第五关 · 兜底 | 守底线 | 降级 + 熔断 + 主从冗余消单点 | 《高并发三板斧》《高可用》 | 任一环出问题,系统别整个雪崩 |
一句话收尾这张表:秒杀没有一招鲜,它是把缓存、限流、原子扣减、MQ、降级冗余这一整套,按"漏斗从外到里"的顺序摆好,合起来才扛得住。 这也正是这篇练习真正想体会的——架构不是单个技术多牛,而是把合适的零件,放到合适的位置上。
名词解释
- 秒杀(Seckill / Flash Sale):在极短时间内,海量用户抢购少量商品的高并发场景;特点是瞬时洪峰、绝不能超卖、刷子多、热点极端集中。
- 页面静态化:把活动期间基本不变的页面预先生成静态 HTML,推到 CDN 缓存,用户就近获取,请求不进源站机房。
- CDN(内容分发网络):把静态资源缓存到各地边缘节点,用户就近取,请求到不了机房(见《缓存架构》篇)。
- 多级缓存:在"应用 → 缓存 → DB"链路上铺多层缓存(CDN / 网关 / 本地 / Redis),流量逐层衰减(见《缓存架构》篇)。
- 超热点 key(Hotkey):被极高频访问的单个 key,集中压在一个缓存分片上,加分片也分摊不掉,标准解法是提到本地缓存。
- 答题 / 滑块错峰:点抢购前先答题或拖滑块,把瞬时尖峰摊平成几秒的小坡,同时顺手挡一批脚本(既削峰又防刷)。
- 限流(Rate Limiting):单位时间内只放过固定数量请求,超额拒绝或排队;秒杀里做成网关层 + 用户/IP 层多层(见《高并发三板斧》篇)。
- 售罄标记前置:在 Redis 放一个"是否售罄"的布尔标记,卖光后请求第一步就被它拦下,不再走后续链路——挡掉秒杀里最大一片"扑空"流量。
- 令牌桶(Token Bucket):恒定速率发令牌、请求先取令牌,允许一定突发又有均值上限,最常用的限流算法。
- 预扣库存:活动前把库存灌进 Redis 作实时账本,抢购时在 Redis 里原子扣减、扣成功才算抢到资格,真正落库延后异步做。
- 超卖:卖出量超过实际库存(如 100 件卖出 101 件);根源是并发下"判断库存"和"扣减"之间被插队,解法是把两步焊成原子操作。
- Lua 脚本(Redis):把"判断 + 扣减"等多步逻辑写进一段 Lua 交给 Redis 一次性原子执行,中途不被其他请求插入,是秒杀扣库存防超卖的关键(见《分布式锁》篇)。
- 分布式锁:跨多台机器/多个资源时保证"同一时刻只有一个请求在改"的锁(Redis 实现常见 Redisson);能用单条原子操作/Lua 解决就别上锁(见《分布式锁》篇)。
- 原子更新(带条件):
UPDATE ... SET stock=stock-1 WHERE stock>0这类靠条件 + 行锁的单语句更新,作为数据库层防超卖的最后兜底。 - 削峰填谷:把瞬时高峰流量先堆进 MQ,让下游(数据库)按平稳速度消化,保护它不被冲垮(见《消息队列》篇)。
- 幂等(Idempotent):同一操作执行一次和多次结果一样;MQ 是至少一次投递,下单消费必须幂等(唯一业务 id + 去重表),否则会出重复订单。
- 防刷:拦截脚本、黄牛、异常账号的组合手段(限流 + 验证码/答题 + 动态接口 + 风控);防的是"流量不公平",与限流(降总量)目标不同。
- 风控:综合设备指纹、账号行为、IP 画像等给请求打分、识别异常的上层智能防线。
- 降级 / 熔断 / 高可用兜底:扛不住时弃车保帅(降级)、坏依赖快速失败(熔断)、关键组件主从冗余消单点,保住核心、不让系统全崩(见《高并发三板斧》《高可用》篇)。
本文属《研发都要懂的事》·服务端架构设计系列——综合实战篇。它不引入新概念,而是把前面的《缓存》《缓存架构》《高并发三板斧》《消息队列》《分布式锁》《高可用》几篇,按"秒杀"这道综合考题串成一条完整链路。串完会发现:架构的功夫,从来不在单个技术多花哨,而在把对的零件,摆到对的位置。
评论(0)
登录后参与评论。
还没有评论,来抢沙发吧。

