b2c电商系统:电商新手进阶版复盘:围绕高并发提炼下一步动作
很多电商新手把高并发理解成“把服务器配置买大”,但我在参与一次大促系统复盘时发现,峰值流量最高的那几分钟,真正拖垮系统的往往不是页面访问,而是库存锁定、优惠计算、订单写入和支付回调同时挤进同一条链路。那次活动的入口访问量只增长了约4.8倍,订单服务的数据库写入压力却增长了近11倍。b2c电商系统进入进阶阶段后,下一步动作不是继续堆机器,而是围绕峰值流量、核心链路、可恢复性和业务取舍重新设计系统。
我建议电商团队不要只盯着QPS或同时在线人数。单独看访问量,很容易把静态资源请求、商品详情查询和订单提交混为一谈。对b2c电商系统更有价值的拆分方式,是分别观察入口峰值、核心接口峰值、单用户操作密度,以及单位时间内真正形成的订单写入量。
这四个指标之间并不是同步增长关系。一个活动页可能带来大量浏览,但由于用户没有登录或没有支付意愿,订单写入并不高。反过来,限时抢购可能只有几万名用户,却因为大家在同一秒点击提交,形成极高的瞬时写入压力。
因此,我在做压测计划时,会要求团队至少画出“访问请求,业务计算,库存操作,订单写入,支付确认”五段链路。只要其中一段仍然依赖同步串行处理,整体吞吐量就会被最慢的那一段限制。

新手阶段最容易犯的错误,是把所有改造都排成“长期架构升级”。真正遇到大促临近、接口已经出现超时的时候,应该先做能快速降低风险的动作,再处理系统结构问题。
这套顺序的价值在于,它把“系统能不能扛住”与“系统是不是足够优雅”分开了。大促前最重要的不是完成架构重构,而是确保用户可以查到商品、提交订单、完成支付,并且系统在失败后不会产生重复扣款或错乱库存。
我见过不少团队写“系统支持十万并发”,却没有说明十万并发对应的是长连接、页面访问还是下单请求。这种目标无法用于采购、压测或故障演练。更实用的写法,是把每个业务动作对应的目标延迟、失败率和降级方式写清楚。
| 业务动作 | 普通时段目标 | 活动峰值目标 | 允许的降级方式 | 不能牺牲的结果 |
|---|---|---|---|---|
| 商品详情查询 | 平均响应小于300毫秒 | 平均响应小于800毫秒 | 延后展示个性化推荐 | 价格、库存状态不能错误 |
| 购物车读取 | 平均响应小于400毫秒 | 平均响应小于1秒 | 暂时隐藏部分营销提示 | 商品数量和选中状态准确 |
| 提交订单 | 成功率高于99.9% | 成功率高于99.5% | 关闭非必要优惠试算 | 不能重复下单或错扣库存 |
| 支付回调 | 5分钟内完成处理 | 15分钟内完成处理 | 进入可重试队列 | 支付状态最终一致 |
一家电商品牌的日常订单量并不高,并不代表它没有高并发风险。直播间、短信通知、社群提醒、平台活动和限时优惠,会把原本分散在一天内的访问,压缩到十几分钟甚至几十秒里。用户总量不大,但操作时间高度重叠,同样会形成尖峰。
我在复盘一类限量商品活动时,把用户行为按秒展开,发现真正危险的不是活动开始前的浏览,而是开始后的第3秒到第18秒。大量用户已经提前打开页面,活动按钮一旦可点击,就同时触发库存查询、优惠校验、地址读取和下单请求。页面看起来只是一次点击,后台却可能连续调用十多个接口。
这也是为什么“日均订单量”不能作为高并发容量的主要依据。日均数据适合估算存储规模、客服工作量和财务对账,不适合直接估算瞬时连接数、数据库锁竞争和消息堆积。

有一次活动中,监控面板显示网页访问正常,商品详情接口的平均响应也只有420毫秒,但用户不断反馈“点了提交没有反应”。进一步排查后发现,提交订单接口需要同步调用优惠服务、库存服务、地址服务和风控服务。四个服务的平均响应都不算慢,可它们的延迟叠加后,接口尾延迟已经超过了3秒。
更麻烦的是,前端在2秒后自动重试,部分用户又手动点击一次,导致同一用户在短时间内产生多次订单请求。数据库并非完全不可用,而是在锁等待、连接池耗尽和重复请求之间反复震荡。最后,团队临时关闭复杂优惠计算,并把订单请求改成带幂等号的异步确认,系统才逐步恢复。
这个案例说明,平均响应时间很容易掩盖真实风险。高并发场景需要重点看P95、P99、超时率、连接池等待时间和锁等待时间。平均值正常,不代表最慢的那1%请求没有拖垮用户体验。
一个成熟的b2c电商系统,不一定要让所有功能在峰值期间都保持完整。新手团队应该先明确最小可成交闭环:用户能否识别商品、确认价格、确认库存、提交收货信息、完成支付,并在后续收到准确的订单状态。
这张清单比“所有接口都要高可用”更有执行价值。因为高并发时资源必然有限,团队真正要做的是把有限资源优先给成交闭环,而不是平均分配给所有功能。
增加实例数量确实能缓解应用层压力,但它无法自动解决数据库锁竞争、第三方接口变慢、重复提交、缓存击穿和消息积压。如果订单服务每次请求都要同步写入多张表,应用层从10台扩展到30台,可能只是让数据库更快达到瓶颈。
我会把扩容前后的链路分成三层观察:入口是否被挡住,应用是否有足够处理能力,存储是否承受得住写入。如果只看应用CPU,容易得到“还有余量”的错误判断;但数据库连接池等待时间已经超过1秒时,系统实际已经进入高风险状态。

缓存可以降低数据库读取压力,但它不是“把数据库复制到内存里”这么简单。商品详情、分类树、地区数据适合缓存,实时库存、订单状态和支付状态则需要更谨慎。尤其是库存数据,如果缓存更新和真实扣减之间存在时间差,用户看到的“有货”可能只是过期状态。
另一个常见问题是缓存击穿。团队为商品详情设置了统一过期时间,活动开始后大量热门商品同时失效,结果请求在同一时刻回源数据库。表面上看系统使用了缓存,实际上缓存失效瞬间形成了集中读压力。
我的处理方式通常是先给数据分类,再决定缓存策略:
| 数据类型 | 典型内容 | 缓存建议 | 主要风险 |
|---|---|---|---|
| 低频基础数据 | 地区、分类、品牌属性 | 长时间缓存,版本变更主动刷新 | 更新不及时但通常不影响成交 |
| 高频展示数据 | 商品标题、图片、详情摘要 | 设置随机过期时间,配合预热 | 缓存同时失效造成回源洪峰 |
| 强一致交易数据 | 可售库存、订单金额、支付状态 | 缓存只做加速,最终结果以交易存储为准 | 脏数据导致超卖、错价或状态错误 |
消息队列可以削峰,但消息队列本身不会让业务自动正确。只要消费者处理速度低于生产速度,积压就会持续扩大。更隐蔽的问题是,订单创建成功后,库存消息、通知消息和营销消息可能被放在同一个队列里,低价值消息就会阻塞高价值消息。
我建议至少按业务优先级拆分队列,并为每条消息定义重试次数、死信处理、幂等键和人工介入方式。支付状态变更与营销积分发放不应该使用同一套消费优先级,因为两者对用户和资金的影响完全不同。

一次压测成功,只能证明某个脚本在某组参数下跑通了。真正接近生产环境的压测,还要模拟用户重复点击、网络抖动、支付回调延迟、库存不足、服务重启和消息重复投递。
我会特别关注三个问题:请求超时后,前端是否会重试;服务重启后,未完成订单是否能恢复;同一支付通知到达两次时,订单和资金是否只变更一次。高并发系统的成熟度,往往不是体现在“完全不失败”,而是体现在“失败可控、状态可追踪、结果可恢复”。
如果一个提交订单请求依次调用五个服务,那么整体响应时间并不是看其中某个服务的平均值,而是看这些服务在高分位延迟下的叠加效果。假设商品服务P99为300毫秒,优惠服务P99为450毫秒,库存服务P99为500毫秒,地址服务P99为250毫秒,订单写入P99为700毫秒,最终用户感知的尾延迟很可能已经超过2秒,还没有计算网络和序列化开销。
因此,优化顺序不能只选择“平均响应最慢的服务”,而要找出同时满足以下条件的节点:
很多时候,最值得优化的不是最复杂的服务,而是最靠近交易入口、最容易触发重试、又拥有大量下游依赖的服务。
数据库是否成为瓶颈,不能只看CPU和磁盘利用率。交易型系统中,锁等待、连接池、慢查询和日志写入通常更早暴露风险。
| 观察信号 | 可能原因 | 应采取的动作 |
|---|---|---|
| 连接池等待持续升高 | 连接未及时释放,或数据库处理速度不足 | 检查慢查询、事务范围和连接池上限 |
| 库存表锁等待集中 | 热点商品写入集中在同一行或同一分片 | 优化扣减模型,减少事务内无关操作 |
| 慢查询数量不多但延迟极高 | 低频复杂查询占用大量资源 | 拆分查询、增加索引或迁移到分析链路 |
| 日志写入延迟上升 | 事务提交和日志刷盘成为限制 | 核查事务大小、批量策略和存储能力 |
这里有一个常被忽略的判断:数据库CPU低,不代表数据库没有压力。如果大量请求正在等待锁、等待连接或等待磁盘写入,CPU甚至可能因为线程阻塞而显得不高。排查时一定要把资源利用率和等待事件放在一起看。

高并发改造不应该按照技术热度排序,而应该按照业务影响和改造成本排序。比如,给订单提交增加幂等键通常成本不高,却能直接降低重复订单风险;而全面拆分服务可能需要数周甚至数月,未必适合活动前临时实施。
| 动作 | 业务影响 | 改造成本 | 优先级判断 |
|---|---|---|---|
| 提交订单增加幂等键 | 降低重复订单和重复扣库存 | 低 | 立即执行 |
| 关闭峰值期间非必要推荐 | 减少下游查询和计算 | 低 | 活动前执行 |
| 库存扣减链路专项压测 | 识别超卖和锁竞争风险 | 中 | 近期执行 |
| 订单与营销服务全面拆分 | 长期降低耦合 | 高 | 稳定期执行 |
| 重新设计存储分片方案 | 提升长期扩展能力 | 高 | 数据规模触发后执行 |
下面这个案例采用脱敏后的情景数据,业务是一家拥有自营商城、会员体系和限时优惠的消费品牌。活动预计持续30分钟,峰值访问约为平日的5倍,团队原本认为现有应用实例足够,因此只做了简单的缓存预热。
压测结果显示,商品详情查询平均响应为280毫秒,P99为1.6秒;提交订单平均响应为1.1秒,P99达到6.4秒;订单接口超时率为3.7%。数据库CPU只有62%,但连接池等待最高达到1.8秒,库存记录锁等待最高达到920毫秒。
排查发现,订单提交接口同时执行了优惠券校验、会员等级计算、库存锁定、订单创建、积分预占和营销日志写入。只要其中一个环节变慢,整个请求就会占用数据库连接,进一步拖慢后续请求。

团队没有立即进行大规模服务拆分,而是先把订单创建定义为一个最小事务:校验商品和价格版本、确认库存可扣减、写入订单主记录、生成待支付状态。积分预占、营销日志、消息通知和用户标签更新全部改为订单创建成功后的异步动作。
优惠计算也进行了分层。固定满减和商品直降在活动前生成规则快照,提交订单时只做规则编号校验;复杂的会员权益继续保留实时计算,但增加最大处理时间,超时后不再阻塞订单主链路。
这里的关键不是“所有优惠都异步”,而是将会影响订单金额的计算保留在可控链路内,把不会改变本次成交结果的附加动作移出去。系统设计必须服从资金和库存的准确性,而不是单纯追求接口响应更快。
每次提交订单都生成业务幂等键,通常由用户标识、购物车版本和客户端请求号组合而成。服务端在创建订单前先判断该幂等键是否已经处理,处理中的请求返回处理中状态,已成功的请求直接返回原订单,失败的请求按明确规则允许重试。
库存扣减也不能只依赖前端按钮禁用。前端控制只能减少正常用户的重复点击,无法处理网络重传、服务重试、代理重试或恶意重复请求。真正可靠的保护必须在服务端完成,并且要把“扣减成功”“订单创建失败”“支付超时”这些状态分别记录下来。
订单请求处理原则:
校验业务幂等键是否存在
校验商品价格版本与活动规则版本
在短事务内完成库存确认与订单主记录写入
返回订单编号和待支付状态
通过消息通知处理积分、营销记录和用户提醒
消费端以订单编号和事件编号完成幂等
经过链路收敛、规则预计算、异步化和幂等处理后,订单接口平均响应从1.1秒降至420毫秒,P99从6.4秒降至1.9秒,超时率从3.7%降至0.4%。更重要的是,活动期间没有出现重复订单,支付回调延迟虽然短时升高,但最终都能够通过队列重试完成。
这次复盘让我更加确认:性能优化不能只写“接口变快了多少”,还要写“失败后是否可恢复”“异常状态是否可解释”“业务是否需要人工补偿”。如果平均响应改善了,却出现支付成功但订单未生成,系统并不能算真正优化完成。

如果系统日订单量还不高,团队不需要一开始就建设复杂的分布式架构。这个阶段更值得投入的是统一订单状态、补齐关键日志、建立接口超时策略、设计幂等键,并且完成一次接近真实用户行为的压测。
这个阶段最怕的是“平时没问题,所以不需要设计异常流程”。实际上,订单量越小,团队越容易忽略数据修复工具;一旦出现少量异常,也可能需要研发手工修改数据库,留下更大的审计风险。
进入这个阶段后,系统的主要问题通常不再是单个接口慢,而是热点商品、热门活动、消息积压和数据库写入集中。团队要开始做商品维度的访问分布分析,不能只看整体平均流量。
如果80%的请求集中在20个商品上,那么给所有商品平均分配缓存和数据库资源并不经济。应当针对热点商品做提前预热、随机过期、请求合并和访问限流;对订单写入则要单独观察事务耗时、锁等待和日志写入。

当订单规模进一步扩大,单体系统并不一定马上失效,但所有模块共享同一个发布节奏、数据库和故障边界,会让任何一次改动都变得谨慎。这个阶段需要根据业务域拆分商品、库存、订单、支付、营销和履约,并为高峰期制定独立的容量模型。
拆分服务前要先问三个问题:数据边界是否清晰,团队是否能维护独立服务,故障是否真的需要隔离。如果只是为了追求架构图上的“微服务数量”,却没有独立监控、发布、回滚和故障处理能力,拆分后只会增加运维复杂度。
容量模型至少应包含以下输入:
预算有限时,我不会首先建议团队购买最贵的数据库或一次性部署大量实例。更高价值的投入通常是监控、日志、压测环境、消息重试、备份恢复和应急开关。这些能力未必直接提升峰值吞吐,却能显著降低故障持续时间和人工处理成本。
例如,系统多承受20%的访问量,并不一定比故障后能在15分钟内恢复订单状态更有价值。电商系统的损失不仅来自服务不可用,还来自错价、超卖、重复扣款、退款积压和客服补偿。
商品详情可以优先响应速度,库存和支付状态则应该优先准确性。一个常见做法是让缓存承担展示层压力,让交易存储承担最终判断。用户看到的库存提示可以存在短暂延迟,但提交订单时必须再次完成真实库存校验。
如果业务是低价高频商品,短暂库存提示偏差可能被用户接受;如果业务是高价商品、定制商品或库存极少的限量商品,就应当减少缓存结果对成交判断的影响,并设计更明确的预占和释放机制。
同步下单的优势是用户反馈直接、流程容易理解,适合库存充足、交易链路简单的商品。异步下单可以吸收流量洪峰,适合限量商品或活动峰值明显的场景,但用户需要接受“排队中”“处理中”的状态,客服和订单查询也要配套升级。
| 场景 | 更适合的模式 | 主要收益 | 主要代价 |
|---|---|---|---|
| 日常普通商品 | 同步下单 | 反馈直接,用户理解成本低 | 峰值吸收能力有限 |
| 限时限量商品 | 排队或异步确认 | 保护库存和核心交易服务 | 需要解释处理中状态 |
| 复杂定制商品 | 半同步流程 | 先确认关键参数,再异步生成订单 | 流程较长,状态设计复杂 |
| 高客单价商品 | 强校验同步流程 | 降低错价、风控和库存争议 | 响应时间和人工审核成本较高 |
库存扣减、订单金额和支付状态不适合无限制地追求最终一致。它们一旦出现短时间错误,可能直接造成资金或履约问题。相反,积分、消息通知、用户标签和销售报表通常可以接受最终一致。
判断标准不是技术人员觉得哪个模块“重要”,而是问:如果这个数据延迟十分钟,用户是否会多付款、少付款、重复下单或无法收货?如果答案是否定的,就可以考虑异步化;如果答案是肯定的,就应该保留强校验、补偿和审计链路。

小团队使用托管数据库、托管缓存和托管消息服务,通常可以缩短上线时间,减少值班和备份工作;但也要关注服务商的限流规则、跨区域延迟、数据导出能力和故障沟通机制。托管并不等于不用设计容灾,只是把部分基础设施工作交给了外部服务。
大型团队可能会逐步自建部分基础能力,但自建的成本不仅是服务器和研发人力,还包括升级、监控、漏洞修复、值班、应急预案和人才依赖。选择时应把三年总成本和业务损失风险放在一起比较,而不是只看当月账单。
第一周不要急着改架构,先把事实补齐。团队需要从日志、订单系统、支付记录和监控平台中整理出活动前后的请求曲线,找出峰值发生在哪个时间段、哪个接口、哪个商品和哪个数据表。
第二周的目标是减少同步链路,不追求一次性完成所有技术债治理。先移出通知、积分、营销记录和报表更新,再为订单提交和支付回调补齐幂等机制。
压测脚本要尽量接近真实用户路径,包括提前打开商品页、活动开始后集中点击、优惠校验失败、库存不足、支付延迟和重复提交。压测数据应当记录到秒级,才能看到尖峰如何形成。
建议至少设计四组场景:
| 压测场景 | 主要验证内容 | 通过标准 |
|---|---|---|
| 常规高峰 | 持续访问和正常下单 | 核心接口P99在目标范围内 |
| 瞬时尖峰 | 数秒内集中提交订单 | 限流生效,订单不重复、库存不超卖 |
| 下游变慢 | 模拟支付、优惠或物流服务延迟 | 核心订单不被无限阻塞 |
| 服务重启 | 模拟消费者和订单服务中断 | 消息可恢复,状态可追踪,数据可补偿 |
如果故障演练只有研发参加,结果通常会偏技术化。客服、运营、财务和仓储人员也需要知道系统出现延迟时应该看什么、如何向用户解释、哪些订单可以自动恢复、哪些订单必须人工复核。
我建议演练至少覆盖三种情况:支付成功但订单显示处理中、订单创建成功但库存状态延迟、用户重复点击后生成多个请求。演练结束后,不要只记录“系统恢复时间”,还要记录客服确认耗时、人工核对数量和最终补偿金额。

每次大促或新品活动前,都应该有一份可以签字确认的准入清单,而不是依赖某位资深工程师临场判断。
流量模型会变化,用户行为会变化,商品结构也会变化。去年有效的缓存时间、限流阈值和数据库容量,今年未必仍然适用。每次大型活动都应该重新采集峰值数据,并将真实结果反馈到下一次容量模型中。
复盘也不应只问“系统有没有挂”。更值得问的是:哪个环节最先变慢,哪些用户被影响,哪些请求被重复发送,哪些异常最终靠人工解决,哪些功能在高峰期间其实没有必要存在。
我对高并发系统的判断标准很明确:不是所有功能都必须同时可用,而是核心交易必须在可控边界内继续运行,非核心功能失败时不能反向拖垮订单、库存和支付。
如果推荐服务不可用,用户仍然应该能够购买;如果积分延迟,订单仍然应该准确生成;如果支付回调短暂积压,系统仍然应该能够通过重试最终确认;如果活动流量超过预期,系统应该优先保护交易闭环,而不是让所有接口一起超时。
如果你现在只能做三件事,我建议按以下顺序执行:
我的独特判断是:b2c电商系统从新手阶段进入进阶阶段的标志,不是部署了多少实例,也不是用了多少种中间件,而是团队能否清楚回答“峰值到来时,哪些功能必须保住、哪些功能可以牺牲、失败之后如何恢复”。
下一步可以从最近一次活动或日常订单峰值开始,整理一张五段链路表,标出每个节点的请求量、P99延迟、失败动作和负责人。先用数据确认最危险的一个瓶颈,再用四周计划完成止血、拆链、压测和演练。这样做出来的高并发能力,才不是停留在架构图上的承诺,而是能够在真实交易压力下持续兑现的业务能力。
我刚开始做电商系统时,看到接口平均响应时间升高,第一反应是给数据库加索引,结果索引加了不少,峰值期间订单接口仍然超时。我现在更想知道,面对高并发故障,怎样判断真正的瓶颈在应用、数据库、缓存,还是下游服务?
我复盘高并发问题时,不会先问“该不该上微服务”,而是先把一次请求拆成完整链路:网关排队、应用计算、缓存访问、数据库连接、库存锁等待、支付或物流等外部调用。因为平均响应时间很容易掩盖问题,真正影响用户体验的通常是 P95、P99 延迟和错误率。
有一次压测中,接口平均响应时间只有 180ms,但 P99 已经达到 3.8 秒。继续看监控后发现,应用 CPU 只有 48%,数据库 CPU 也不到 60%,真正异常的是数据库连接池:最大连接数 300,活跃连接长期超过 285,部分请求在连接池里等待了 2 秒以上。
我建议新手先建立一张“现象,指标,动作”表: 现象优先检查指标常见动作 CPU 接近 90%,接口计算耗时上升CPU、线程池、GC、单机吞吐减少同步计算、扩容实例、优化热点代码 连接池耗尽,应用线程大量等待活跃连接、等待时间、慢查询缩短事务、修复连接泄漏、限制并发访问 缓存命中率下降命中率、热 key、缓存网络延迟拆分热点 key、设置合理过期时间、增加本地缓存 库存接口锁等待明显锁等待、事务时长、回滚率缩短事务、调整扣库存策略、避免大范围锁定 我的判断标准是:先处理“排队时间”,再处理“单次执行时间”。
如果请求大部分时间都在等待连接、锁或下游响应,盲目优化代码几乎没有收益。只有当排队问题解除后,才值得继续优化 SQL、序列化和业务逻辑。下一步动作可以按优先级执行:第一,补齐链路追踪和 P95、P99 监控;第二,为数据库连接池、线程池和队列设置上限;第三,对库存、下单、支付等关键接口分别压测;
第四,建立超过阈值就自动降级的策略。高并发不是单纯追求更高 QPS,而是让系统在压力上升时仍然保持可预测。
我准备搭建一个面向消费者的电商系统,预计早期每天订单量并不大,但后续可能遇到大促和直播流量。我担心单体架构以后难以扩展,也担心一开始拆成很多服务后,部署、排查和数据一致性都会变复杂,到底应该如何取舍?
我的经验是,电商新手最容易把“高并发”误解成“必须微服务”。实际上,高并发首先考验的是缓存、数据库、连接池、消息队列和限流设计,服务数量本身并不会自动提升吞吐量。一个边界清楚、模块化良好的单体系统,往往比十几个边界混乱的服务更容易稳定运行。
在一次早期项目评估中,我们把用户、商品、订单、库存和营销代码都放在一个应用里,但按领域划分目录、接口和数据访问层。经过压测,单实例可以稳定处理约 420 次每秒的商品查询请求,瓶颈反而出现在促销规则计算和库存事务,而不是单体架构。我通常用三个问题决定是否拆分: 第一,某个模块是否需要独立扩容?
例如商品详情读取量可能是订单写入量的几十倍,如果两者必须整体扩容,资源浪费会比较明显。第二,某个模块是否有独立发布节奏?营销活动频繁变化,但订单和库存要求稳定,如果每次营销改动都必须重新发布全部系统,拆分的价值才会增加。第三,团队是否能承担分布式系统成本?
拆分后要面对服务发现、链路追踪、超时重试、幂等、消息积压和数据一致性。如果团队没有监控、发布和故障演练能力,微服务可能会把简单故障变成跨服务故障。
阶段更适合的架构重点动作 验证商品和交易模型模块化单体先划清商品、订单、库存、支付边界 出现明显读写热点单体加缓存、队列和读写分离优先解决数据库与外部调用瓶颈 某模块需要独立扩容或独立发布渐进式拆分先拆商品查询、营销或文件服务等相对独立模块 多个团队并行开发服务化架构补齐治理、监控、权限和容灾能力 我会建议先采用“可拆分的单体”,而不是“预先拆好的微服务”。
关键是让模块之间通过清晰接口交互,避免跨模块直接读写对方表。这样在流量和组织规模真正达到拆分条件时,可以渐进迁移,而不是重写整套系统。
我以前做压测时只设置了一个接口,例如不断请求商品详情,最后得到一个很漂亮的吞吐量数据。但真正大促时,用户会搜索、加购、提交订单、支付,系统表现和单接口压测完全不同。我想知道,一次有参考价值的电商压测应该如何设计场景、指标和通过标准?
高并发压测最常见的误区,是把“接口能处理多少请求”当成“系统能承受多少用户”。电商流量具有明显的读写比例、访问路径和时间波峰,如果只压商品查询,缓存命中率会很高,数据库写入、库存锁和消息积压等真实风险根本不会出现。我做压测方案时,会先建立用户行为模型,而不是先填写一个并发数。
一个较实用的初始模型可以是:商品浏览占 70%,搜索占 15%,加购占 8%,提交订单占 5%,支付回调和售后等写操作占 2%。之后再根据真实日志修正比例。大促场景还要单独增加热门商品和突发流量,不能用平均分布代替。
压测至少分为四轮: 第一轮是基线测试,使用少量并发确认功能正确,并记录正常状态下的响应时间、数据库连接和缓存命中率。第二轮是阶梯加压,例如每 5 分钟增加 20% 流量,观察系统在哪个区间开始出现 P99 抖动、错误率上升或队列积压。
第三轮是突刺测试,模拟 30 秒到 2 分钟内流量突然增加 3 至 5 倍,重点验证限流、缓存预热和自动扩容是否有效。第四轮是耐久测试,保持目标流量 2 至 4 小时,观察内存泄漏、连接未释放、日志膨胀和消息消费延迟。
指标建议关注方式不能只看什么 响应时间P50、P95、P99 分层观察不能只看平均值 稳定性错误率、超时率、重试率不能把客户端重试后的成功当成真实成功 数据库慢查询、锁等待、连接池、事务时长不能只看 CPU 利用率 消息系统积压量、消费延迟、重复消费不能只看生产成功 我会把“通过”定义为一组条件,而不是单一 QPS。
例如目标流量下 P95 小于 500ms、P99 小于 1.5 秒,错误率低于 0.1%,库存不能超卖,消息积压在 5 分钟内恢复,核心接口在单个实例故障后仍能继续服务。只有把业务正确性也纳入标准,压测结果才有决策价值。
我经历过一次活动结束后的复盘,会议上列出了二十多项问题:缓存容量不足、数据库慢查询、监控缺失、客服无法查询订单、发布流程也不够稳。问题很多,但研发资源有限,我不想把复盘变成一份没人执行的清单,应该怎样判断哪些动作最值得优先做?
复盘最怕变成“问题目录”。我现在会把每个问题放进两个维度:它对用户和交易的实际影响有多大,以及修复后能否降低下一次事故概率。只按技术难度排序,往往会先做一些容易提交代码、但对核心风险帮助不大的优化。可以采用一个简单的优先级公式:优先级分数 = 影响范围 × 发生概率 × 恢复难度 ÷ 实施成本。
每项按 1 到 5 分估算,不追求数学精确,而是迫使团队把“感觉很重要”变成可讨论的判断。
问题影响范围恢复难度优先动作 库存扣减存在超卖风险55先补幂等、库存约束和异常对账 订单接口 P99 偶发超过 5 秒54拆解链路,定位锁等待和下游超时 日志字段不统一32统一请求 ID、订单 ID 和错误码 后台报表加载较慢22延后处理,避免挤占核心交易资源 我建议把动作分为三个时间窗口。
24 小时内完成止血项,例如关闭高风险非核心功能、增加限流、补充告警和人工兜底。两周内完成根因修复,例如缩短事务、处理连接泄漏、完善幂等和消息重试。一个月内完成体系建设,例如故障演练、容量模型、发布回滚和跨团队值班机制。每项行动都必须写清四个字段:负责人、完成日期、验证指标、失败后的回滚方案。
比如“优化订单性能”不是可执行任务,改成“将订单提交接口 P99 从 2.1 秒降至 800ms 以下,并在 2 万次每秒混合场景下连续运行 30 分钟”,才可以验收。我特别重视“复盘后再验证”。修复完成不代表风险消失,必须重新压测或进行故障演练,确认错误率、队列积压、库存一致性和恢复时间确实改善。
真正有价值的复盘,不是写出最多问题,而是让下一次高峰少依赖临场救火。


读者评论
文章把高并发拆成入口、业务、写入和失败四类指标,这个思路比单看QPS更贴近电商实际。尤其是订单写入增长远高于入口流量,能提醒团队重点关注数据库和锁竞争。
先止血、再拆链、后优化”的顺序比较务实。大促前优先保障价格、库存、订单和支付准确,暂时关闭推荐等非核心功能,确实比仓促重构更可执行。
文中对缓存和消息队列的风险分析比较客观。缓存不能替代交易存储,队列也需要优先级、幂等和死信处理。若能补充更多真实压测数据和实施成本,参考价值会更高。