资讯动态

赛事高并发架构实战:四层分流设计深度解析

发布时间:2026/9/17 1:59:51 来源:尧图企业网站定制
决赛夜那晚我盯着监控大屏接入层的QPS曲线在开赛前二十分钟直接竖成了直角。说实话这种场面见过很多次但每次到这个节点肌肉还是会绷紧。“星逐赛事”这套源码最初就是奔着这个场景去的——赛事直播、实时比分、竞猜投票、弹幕互动全挤在同一个比赛日里爆发。它最值得聊的不是某个具体功能点而是接入层、业务层、数据层、流媒体层这四层围绕“高峰分流”做的整套设计。如果你正准备搭一套赛事、直播互动、投票竞猜类的后端系统或者单纯想看看一套真实项目怎么做流量治理这篇东西应该能给你一些能直接拿去用的思路。1. 赛事流量的“反电商”特征为什么秒杀方案直接抄会翻车很多人一听高并发第一反应就是抄秒杀方案。但赛事流量有三个和秒杀明显不一样的地方这套源码前期做架构讨论时我们最先吵清楚的也是这三件事。把这几个特征聊明白后面看四层分流设计时你才能对上号。1.1 峰值可预判但曲线比秒杀更陡秒杀的特点是人为制造定点脉冲流量集中在开场前几秒到几十秒赛事不一样赛程表早就写好了你完全知道哪天哪场会火但用户不会等到开赛那一秒才来。以一场热门赛事为例开赛前10到20分钟用户就开始成批进入直播间、刷新赛程页面、拉取阵容数据开赛瞬间比分订阅和竞猜流量同时顶上比赛进行中每出现一次进球、一次争议判罚都会在几十秒内产生一串尖峰。整个流量曲线不是单峰而是“高位平台加一堆毛刺”。这对分流设计的影响很直接你不能像秒杀那样只准备一个短时高水位而是要在一个持续几个小时的高位区间内始终保留足够的缓冲能力。星逐在做容量规划时按“平台期均值的3到5倍”来预留峰值空间而不是按一个固定QPS上限去规划机器。说白了比赛日的流量是波浪式的你的系统必须在这个波浪里一直站稳。1.2 读写比例会随赛程阶段倒挂赛事系统另一个“怪”的地方在于读写比例是动态变化的。赛前大量用户在查赛程、查历史交锋、查阵容读请求占绝对主导赛中竞猜、投票、弹幕、点赞这些写请求开始暴涨赛后比分落定用户又回到回放点播、数据统计这类读请求上。也就是说数据层不能只按“读多写少”或者“写多读少”来设计它必须同时扛得住读峰值和写峰值而且这两类峰值很可能就出现在同一天的不同时段。如果只按读峰值设计缓存比赛中的写入潮会把主库打垮如果只按写峰值设计队列赛前和赛后的读请求又会把缓存链路堵死。星逐的处理方式很朴素把读路径和写路径彻底分开设计。读路径靠三级缓存削峰写路径靠队列削峰两条路互不拖累。这一条写进架构文档之后后续所有选型都围着这个思路走。1.3 流媒体流量和 API 流量同时冲击市面上的高并发方案大多只考虑HTTP API但赛事系统绕不开流媒体。同一个用户在看直播的同时客户端往往还在拉比分接口、维持弹幕长连接这意味着带宽和连接数是同时被两套流量占用的。如果接入层不把入口拆开一个热门直播间的拉流流量就可能把整个网关的连接池拖垮普通用户连接口列表都刷不出来。这个坑我们在早期联调时踩过当时直播和API共用一台入口机压测刚跑到一半拉流带宽直接把API请求挤到超时后面整整排查了一个下午才发现是连接池被流媒体连接占满了。所以星逐在接入层一开始就坚持“分门别户”Web API、流媒体拉流、推流上传各走各的域名各走各的负载均衡宁可多花一点机器也不让两股流量在入口处互相挤压。这个决策给后面所有分流设计打下了基础。1.4 星逐的分层思路每层只处理自己该处理的压力简单描述一下这套源码的整体分流骨架用户端先经过接入层接入层负责连接接入、路由、限流和基本的防刷然后进入业务层业务层负责状态管理、流量削峰和消息推送数据层负责缓存、持久化、分片流媒体层独立成一条旁路负责转码和分发。赛事管理后台则是另一套完全独立的链路用的是基于 Vue Pure Admin 模板加 Node 服务层再接 MySQL 的方案跟用户链路彻底隔离平时后台的报表查询再重也不会影响线上业务。四层之间没有复杂的耦合每一层都在把能卸载的压力往边缘卸。接入层能挡掉的重复请求就挡掉业务层能异步处理的写入就不同步阻塞数据层能走缓存的就不落库流媒体层能交给CDN的就不回源。这套源码真正“值钱”的地方也就在这里。2. 接入层分流四层接连接七层管路由限流要按业务拆接入层是整个系统的第一道闸门也是比赛日最先感受到压力的地方。大部分系统接入层出问题都不是某一台机器配置不够而是入口设计没有做好分层。星逐在这层做的事可以拆成四个部分来看。2.1 域名与线路拆分让流媒体和 API 各走各的门先说入口域名拆分是最基础也最容易被忽略的一步。星逐在生产环境里把入口分成三类域名API域名负责业务接口流媒体域名负责HLS拉流上传域名负责推流和图文上传。三类域名通过GSLB做就近调度把不同区域的用户解析到最近的机房节点。这样拆有三个直接好处。第一流媒体带宽被打满时不会影响API域名的解析和连接建立第二流量调度可以分别做策略CDN只对流媒体域名生效API请求完全不经过CDN的缓存层避免接口被错误加速第三故障隔离更干净流媒体边缘节点出问题时可以单独切走不影响普通接口。这里有一个容易被忽略的细节域名拆分之后客户端的连接数会明显变多原本一个域名下的连接被分散到两三个域名。所以接入层的连接数预算要重新算不要按以前单域名的模型去压测。2.2 四层负载与七层负载的分工接入层内部星逐采用了“四层接连接、七层管路由”的两级结构。最前面是LVS这类四层负载均衡只做IP和端口级别的转发吞吐高、延迟低负责把海量连接先接下来往后是Nginx/OpenResty这层七层负载负责HTTP协议解析、路由、鉴权、限流和Header改写。这个分工是有讲究的四层不碰应用层数据所以处理速度极快但它也做不了精细路由七层能拿到URL、Header、Cookie这些信息但CPU开销更大。把两者串起来连接压力被四层先卸掉一大部分七层只处理真正需要路由的请求性能就能拉开差距。如果要在C场景里自研网关可以去看一下muduo这类TCP网络库的事件循环和连接管理方式它在高并发短连接场景下的线程模型思路很有参考价值。星逐本身的网关用的是OpenResty但读源码时对照着理解更容易明白连接处理的瓶颈通常出在哪儿。2.3 网关限流全局令牌桶只是保底业务维度限流才是关键限流是接入层最重要的一件事。只看全局QPS远远不够因为全局限流只能防止系统整体被打死没法防止某个热点赛事把资源全部吃光。星逐的限流key设计了四个维度用户维度限制单用户每秒最多N次请求接口维度每个接口独立配额赛事维度限制单个热门赛事的请求总量IP维度用来防刷。以OpenResty的实现为例接入层网关里可以给数据刷新类接口配比较高的配额因为用户频繁刷比分是赛事场景下的正常行为但竞猜提交类接口的配额要压低因为一个用户短时间内反复提交本身就是异常信号。这样按业务拆限流关键技术指标是每类接口的配额都要经过压测标定不能用拍脑袋的数字。2.4 连接治理接入层真正的瓶颈经常是连接数而不是 CPU比赛日接入层最常见的故障是CPU没满连接先被拖垮。高并发下每个TCP连接都会占用文件描述符和内核内存如果后端upstream没有打开keepalive大量连接反复建连、断连TIME_WAIT状态就会堆积如山。星逐在接入层做了几项常规但很管用的调优。Nginx upstream开启keepalive长连接减少后端服务的建连成本接入层机器的内核参数调整文件描述符上限和SYN队列大小针对短连接场景谨慎开启tcp_tw_reuse尤其在用户经过NAT的场景下复用TIME_WAIT连接可能串包这个问题排查起来非常隐蔽。实测下来这些参数调完接入层单机承载的连接数能提升一到两倍。3. 业务层分流把状态从内存里赶出去把写请求排进队列接入层挡住了刷量流量后真正有意义的高并发请求会落到业务层。业务层如果设计不好扩容就是空话。星逐在这层最重要的两个原则一个是无状态化一个是异步化。3.1 无状态化改造扩容之前先解决本地状态业务层最常见的错误是把“比赛进行中”“当前比分”“用户是否已投过票”这类状态直接放在JVM本地内存里。单机部署时没问题一扩容就出问题用户请求被负载均衡分发到不同节点不同节点看到的赛事状态不一样甚至可能出现同一个用户在两台机器上各自投票都提示成功。星逐的做法很明确业务节点全部无状态所有需要跨节点共享的状态都放到Redis。赛事基础信息、当前比分、竞猜状态用Hash或String结构存用户是否已投过票用Set结构存需要计数的用Redis原子操作。节点只负责计算和转发这样水平扩容才真正有意义。后来复盘第一个比赛日我们发现有几次投票计数对不上根因就是本地内存状态在多节点之间不同步。从那以后无状态化被写进了代码评审的强制清单任何新增接口只要引入了持久化的本地状态评审就过不去。这个教训比很多架构文档里写的“无状态化”要疼得多。3.2 写入类流量的削峰先写 Redis再异步落库竞猜、投票、弹幕这类写入请求特点是瞬时并发高、单条数据量小、实时性要求高。如果每个请求都直接落数据库MySQL会先撑不住。星逐的方案是“两级写”用户请求先打到Redis完成计数和幂等校验后立刻返回成功然后通过MQ把数据异步沉淀到数据库。这样用户感受到的响应时间在毫秒级数据库也不用扛住每秒几千甚至几万的写入。MQ选型上星逐用了RocketMQ而不是Kafka。原因是赛事场景对事务消息、延迟消息和消息轨迹的要求更高比如延迟消息可以用于“开赛后自动封盘”这类定时任务消息轨迹在排错时很有用。Kafka在吞吐上更强但赛事系统的写入量其实没有大到非Kafka不可选一个跟业务贴合度更高的中间件后面省心很多。3.3 防超卖与防重复Redis Lua 原子脚本竞猜和投票都有“总数上限”和“每人一次”的限制这两个限制必须在一个原子操作里完成否则高并发下必然超卖。星逐用一段Redis Lua脚本同时完成“检查用户是否已投过票→检查当前票数是否达到上限→计数加一→记录用户”这四个动作。local voted redis.call(sismember, KEYS[2], ARGV[1]) if voted 1 then return 0 end local current tonumber(redis.call(get, KEYS[1]) or 0) if current tonumber(ARGV[2]) then return -1 end redis.call(incr, KEYS[1]) redis.call(sadd, KEYS[2], ARGV[1]) return 1Lua脚本在Redis中是原子执行的这段逻辑不会被打断所以不存在并发窗口。相比“先查Redis再写Redis”的三段式代码Lua脚本把网络往返也从多次降为一次性能和一致性都能兼顾。这里要提醒一下脚本里的KEYS和ARGV不要写死要用参数传进去否则Redis集群模式下会直接报错。3.4 读路径的两级缓存本地缓存 分布式缓存业务层的读数据流量星逐用两级缓存承接Caffeine本地缓存负责单节点内的高频重复读Redis分布式缓存负责跨节点共享。比如“当前比分”这类数据所有用户都在读本地缓存能让每个节点只向Redis请求一次大幅减少Redis压力。这里有个坑要提醒本地缓存的过期时间不能太长星逐设为3到5秒。太短了缓存形同虚设Redis压力下不来太长了不同节点之间数据不一致用户刷新一次看到一个比分切个网络又看到另一个比分客诉马上就来。缓存key的设计也要特别注意。共享数据要用全局key比如match:info:456、match:score:456这样同一节点上的不同用户才能命中同一条本地缓存如果误把用户ID拼进key里像user:123:match:456那本地缓存基本等于失效Redis连接数很快会打满这个我们在后面第7章事故复盘里会细讲。3.5 实时状态推送让客户端别再来回轮询赛事比分、进球事件这些数据如果全靠客户端轮询接入层流量会翻好几倍。星逐的做法是用WebSocket和SSE做服务端推送比分变化由赛事状态机统一触发推送给所有在线连接客户端不需要主动发现变化。如果不想维护长连接至少也要做“带版本号的增量拉取”客户端每次请求带一个版本号比分没有变化时服务端直接返回304变化时再把增量数据返回。这个方案比无脑轮询省太多流量尤其在比赛进入最后十分钟、所有用户同时高频刷新的时候带宽和连接数的差距会非常明显。4. 数据层分流缓存、分库、读写分离一个都不能少数据层是比赛日最容易被冲垮的一层也是分流设计里收益最大的一层。星逐的数据层设计围绕一个核心原则能不进MySQL的请求尽量不进去必须进MySQL的请求尽量分散。4.1 三级读取路径本地缓存、Redis、MySQL 各管一段星逐的数据读取路径是本地缓存 → Redis → MySQL逐级穿透只有前一级没有命中才往下走。这三级的定位完全不同本地缓存管单节点内的热点数据重复读Redis管跨节点共享的热点状态MySQL管最终持久化。这套设计里本地缓存是第一道大坝扛住的是同一节点内几百几千次完全相同的重复请求Redis扛的是跨节点的读热点MySQL实际承压的只有缓存未命中的那一小部分流量。三级穿透的关键是每一级都要有合理的过期时间避免缓存不命中的情况下所有请求瞬间打到数据库。4.2 读写分离与主从延迟监控写入落到MySQL后星逐用了标准的主从读写分离主库承接竞猜、投票、评论这类写请求从库承接赛事列表、历史战绩、排行榜这类读请求。比赛进行中查比分这类最高频的读请求走Redis不从库取避免高频读把从库拖慢导致主从延迟扩大。主从延迟是必须盯的数据。星逐设了一条规则从库延迟超过阈值时相关读取接口自动切到主库或直接走Redis。宁愿让数据库压力大一点也不能让用户看到延迟了好几秒的数据。这条规则在赛后数据统计接口上也同样生效因为赛后用户会集中刷榜单和复盘数据读流量会再冲一波。4.3 分库分表的分片键选择这一步错了后续会很难受赛事系统的核心写入量光靠读写分离扛不住必须分库分表。分片键选哪个是一个“回头想改就非常痛苦”的决策。星逐的分片策略分两类场景用户维度的数据竞猜记录、弹幕流水、投票日志按用户ID分片保证同一用户的所有读写被路由到同一分片赛事维度的高频读数据比分、事件流、回放列表按赛事ID分片方便单场赛事的查询。两类分片各自独立不混用一个分片键。分片键优点缺点适用场景用户ID单用户所有数据集中在同一分片路由稳定赛事维度的查询会跨分片需要一个聚合层竞猜记录、投票日志、弹幕流水赛事ID单场赛事数据集中查询方便热门赛事可能集中访问单分片形成热点比分、事件流、回放列表如果用的是ShardingSphere这类中间件来做分片并发执行链路的理解难度会增加不少。想彻底搞懂SQL是怎么被改写和路由的建议找时间读读MyBatis的源码尤其是SQL解析和参数绑定那部分读懂了之后排查分库分表中间件的“莫名报错”会顺手很多。4.4 缓存穿透、击穿、雪崩三类事故的应对方案赛事场景下这三类缓存事故都可能遇到应对方式不太一样。缓存穿透指请求的数据在缓存和数据库里都不存在无效请求直接打到数据库。星逐用布隆过滤器挡掉明显不存在的key同时对查询结果为空的key也做短时间缓存避免无效请求反复穿透。缓存击穿指某个热点key在过期瞬间大量请求同时打到数据库。应对方式是互斥重建让同一时刻只有一个请求去重建缓存其他请求短暂等待。这里可以用Redis的SETNX做一个重建锁拿不到锁的请求直接返回旧缓存或者短暂降级。缓存雪崩指大量key在同一时间过期数据库瞬间承接所有请求。应对方式是过期时间加随机值让失效点散开。比如基础过期时间300秒每个key再加0到60秒的随机偏移就能有效避免整片缓存同时失效。4.5 数据一致性用最终一致性换吞吐量写入走Redis异步落库之后数据一致性必须接受“最终一致”。星逐的落库链路是Redis写入成功 → MQ投递 → 数据库消费落库同时用Canal订阅数据库binlog做对账发现漏掉的写请求就补写。整个过程不依赖分布式事务因为它带来的连接占用和锁等待在高并发赛事场景下不可接受。这套方案的取舍是极少数用户在极端时间内看到的数据略有延迟但最终一定一致。赛事竞猜、投票这类业务用户真正关心的是“最终我的票有没有被算进去”而不是“我提交那一瞬间数据库里的数字是不是1”。如果所有场景都强求强一致比赛日大概率会先把自己拖垮。5. 流媒体层分流转码、边缘分发和回源保护流媒体层和前面几层完全是两套玩法。HTTP接口是“请求-响应-释放”的模式流媒体链路是长时间占用带宽和连接资源处理思路必须换一套。5.1 流媒体链路和 Web 链路的本质区别Web请求再大单个请求也是毫秒级处理完就释放流媒体不一样一路直播流要持续占用带宽和转码资源好几个小时。比赛日最怕的不是转码算力不够而是时间线拉长后资源被持续占用没有释放窗口。所以流媒体层必须独立部署、独立容量规划跟业务集群完全隔离。星逐把转码集群、源站、流媒体存储单独放在一整套资源池里比赛日的扩容也是单独扩这套绝不会去挤业务集群的机器。5.2 转码算力评估与比赛日扩容转码集群是流媒体层最消耗算力的部分。以H.264 1080P实时转码为例一路实时转码大约需要占用2到4个物理核具体视码率、帧率和编码preset而定如果还要同时输出720P、480P等多路码率资源消耗会成倍增加。星逐在比赛日之前就会把转码任务提前拉起来绝不会等开赛现场创建任务。因为转码服务冷启动要加载编码器、初始化GPU显存现场拉起至少要几分钟开赛那波流量根本等不了。更稳妥的做法是提前按峰值路数启动转码实例再保留一条“一键加节点”的扩容通道观测到转码延迟上升就立刻加。5.3 HLS 分片与 CDN 边缘缓存策略赛事直播推荐用HLS协议。原因很实际HLS把直播切成一个个分片文件通过m3u8索引文件分发走的是标准HTTP协议天然适配CDN缓存。星逐的分片时长设为4到6秒CDN边缘节点对分片做缓存用户拉流的请求绝大多数在边缘就被命中只有边缘缓存未命中的分片才会回源。边缘命中率高不高直接决定了源站的带宽压力。星逐对热门赛事的m3u8索引和最近分片做了主动预热把回源比控制在很低的水平这样源站真正承受的流量是可控的。还有一个细节分片文件在CDN的缓存过期时间不能比分片时长还短否则每个分片都会频繁回源源站压力会成倍上涨。5.4 回源保护别让 CDN 把源站带宽打满CDN的缓存一旦失效回源请求可能瞬间放大好几倍。星逐在源站前面做了三层保护。第一回源URL带签名防止有人绕过CDN直接刷源站第二对单个源IP的回源频率做限制防止边缘节点异常时产生回源风暴第三对分片存储做本地缓存CDN请求同一个分片时源站不会反复转封装。还有一个容易被忽略的点播放器拉流使用的连接池必须和普通API的连接池分开。比赛日拉流连接数可能成千上万混在一起很容易把正常接口的连接池塞满接口一慢用户就会以为系统挂了。5.5 高峰降级优先保画面再保互动流量超过阈值时流媒体层要有明确的降级顺序。星逐的顺序是先关闭弹幕、评论这类非核心互动保住直播画面再对清晰度做降级把部分用户从1080P切到720P甚至480P关键是HLS的码率列表里要提前准备好低码率档位切起来才顺滑极端情况下关闭低延迟模式切回普通延迟模式牺牲一点时延换更稳定的分发。降级的核心逻辑是观众可以接受弹幕没了但不能接受画面卡住。所有降级开关要做到一键生效比赛日期间每半小时检查一次状态发现转码延迟上升或源站带宽接近阈值就立即执行。6. 一次请求的完整旅程从点击到画面链路串联前面几章把四层拆开讲了这一章把它们串起来。比赛日的一条完整请求链路实际上有三条路径在并行走。6.1 Web 请求路径打开赛事详情页用户点开赛事详情页浏览器先做DNS解析API域名被GSLB解析到就近机房到达四层负载均衡后转发到Nginx/OpenResty集群在这层完成鉴权、限流、防刷然后请求进入业务层业务服务先查本地缓存没有命中再查Redis还没有再从库查询最终把赛程、阵容、历史战绩这些数据组装成页面数据返回给客户端。这条路径上每一层都可能随着赛程阶段不同而变化但整体原则是固定的缓存优先数据库兜底。赛事详情页这种“读多写少”的场景一定要在做聚合接口时把数据源拆分清楚哪些从缓存读、哪些从库读、哪些可以异步加载否则一个接口把所有数据都查一遍数据库压力瞬间就上去了。6.2 实时互动路径投票、弹幕是怎么流转的用户投出一票请求先进网关确认限流通过再到业务层。业务层执行Redis Lua脚本完成原子计数和去重返回“投票成功”然后将“某个用户投了某场比赛的谁”这个事件投递到MQ。后端消费MQ将投票明细写进MySQL同时更新赛事维度的缓存汇总数据。弹幕是另外一个方向写入后先发到Redis的Pub/Sub或消息队列的广播Topic由推送模块推给在线用户的WebSocket连接。这两条路径在业务层是分开的但在接入层都是HTTP或WebSocket入口进来的。所以接入层的连接数预算必须把实时互动的连接也算进去否则开赛半小时连接数就涨到阈值。6.3 流媒体路径播放器拉流与码率切换用户点开直播画面播放器请求m3u8索引地址这个地址如果是CDN边缘命中就直接返回如果没有命中CDN回源到流媒体源站源站返回分片并让边缘节点缓存。播放器会根据带宽和缓存的m3u8码率列表自动在1080P、720P、480P几个档位间切换。现场推流质量波动时这种多码率自适应能有效降低卡顿率。需要注意的是m3u8索引的更新频率和分片时长要匹配分片时长6秒索引最好每两三秒更新一次索引更新太慢播放器在切换码率时会出现几秒黑屏观众体感非常明显。6.4 TraceId 贯穿四层排查性能问题先看链路图三条路径跑了几个小时后总会有人反馈“比分刷新慢了”。如果没有全链路Trace你要在四层里反复翻日志才能定位。星逐在网关入口生成一个TraceId随HTTP Header传到业务层、数据层流媒体层也接入同一套日志平台。每层处理都记录耗时排查问题时先打开Trace面板看耗时到底花在接入层、业务层还是数据库查询再针对性处理。这里有一条经验别一上来就加缓存。先看Trace如果慢的是数据库慢SQL加缓存没用如果慢的是网关排队加业务层机器也没用。链路打点是分流设计的仪表盘没有它就只能全靠猜猜着猜着比赛就结束了。7. 压测与线上事故复盘三次峰值期间的真实教训最后分享几个比赛日期间真实踩过的坑。每次复盘之后的改动其实都比平时看文档学到的更有价值。7.1 事故一开赛前所有人刷新页面网关 CPU 先被打满第一次正式比赛日还没开赛网关CPU先报警了。查Trace发现开赛前用户集中刷新“赛事详情聚合接口”这个接口在网关层做了多处数据拼接和过滤CPU全耗在网关的聚合逻辑上。改动方案把聚合逻辑全部下沉到业务层网关只做路由和轻量鉴权同时按接口维度重新配置限流配额详情页接口单独设一个比普通接口高一些的阈值。之后开赛日的网关CPU平稳多了这一条教训也写进了架构规范网关永远不做业务聚合只做转发和控制。7.2 事故二Redis 连接数被打爆本地缓存却没生效第二个比赛日Redis连接数先被打满但看监控发现本地缓存命中率不到5%。排查下来原因是本地缓存key设计成了带用户维度的user:123:match:456但赛事详情这种数据是全量用户共享的每个人一个key本地缓存等于失效。改进方式把共享数据单独设计成match:info:456、match:score:456这类全局key让同一节点上的不同用户能命中同一条本地缓存Redis连接池也做了动态扩容避免一个节点临时故障时把连接集中打到其他节点。这个case我印象特别深因为缓存命中率这个指标平时很少人盯等到Redis被打爆才回头查定位成本高很多。7.3 事故三推流波动导致 CDN 回源放大源站带宽被打满第三个教训来自流媒体层。现场推流偶发波动导致某个分片没有生成完整CDN边缘节点请求分片失败后立刻重试回源多个边缘节点同时请求源站带宽直接被放大打满。改动方案源站对分片请求加了并发控制和本地缓存已经尝试生成但失败的分片会在短时间内直接返回失败而不是反复重试同时提前对热门分片做预热降低边缘未命中的概率。这个问题的本质是“失败重试风暴”在流媒体场景里比Web场景更容易发生因为分片请求天然密集且时间集中。7.4 压测怎么设计才算数分层压测与扩容决策模型比赛前压测不能只测接口要分层压用wrk压API接口的吞吐上限用Locust模拟真实用户行为路径用JMeter做复杂场景编排流媒体链路则用模拟推流工具持续推流再同时模拟大量拉流。压测结果要关注两个数据各个节点在目标QPS下的CPU和内存占用以及各层在故障场景下的降级表现。我的扩容决策模型很简单压测到目标QPS的70%时如果CPU已经超过60%说明余量不够必须扩容或优化如果到70%还很轻松那目标可以再往上调。别等到压到100%再决定生产环境的余量永远要比压测环境多留一点。这个模型不一定适合所有团队但对星逐这种比赛日期间的流量模型实测下来是靠谱的。最后说点个人体会。比赛日值守的时候我反而不太依赖那些花哨的动态扩缩容能力最管用的是网关里那个“一键熔断”的开关关闭聚合接口、把播放器切到低码率、暂时停掉弹幕每个开关都在手边出问题按一下就能保住关键链路。分流设计的本质从来不是把所有流量都接住而是让关键流量永远有路可走。星逐这套四层架构说白了就是围绕这句话反复取舍出来的结果。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价