一、需求
- 有多款商品,每款商品均100件,每人限每款商品最多购买一件。
- 在X月X日 X时X分0秒开启购买。在约定时间之前,只能看到产品页面,购买按钮置灰。
二、活动预估
- 预计每种商品数万人参与
- 活动开始后半分钟内,预计每种商品收到10W次交易请求,预计总TPS:20W/s
- 活动开始半分钟后,预计绝大多数商品已售罄,剩下的商品仍支持秒杀,预计总TPS:2000/s
三、系统现状
- 系统可保持长期稳定运行的最大TPS:1000/s
- 短时间「1分钟内」系统未拒绝服务的最高TPS:1500/s
四、设计预研
方案一:改造现有系统,微服务系统整体大幅增加TPS
优点:
- 大幅增加TPS后,业务系统可直接承载巨量交易请求,应付秒杀需求会更加从容。
缺点:
- 秒杀活动次数少,改造成本、风险较大,性价比低
- 改造后,系统架构会更加复杂,可维护性降低
方案二:开发新应用,承载该需求;改造现有应用以支持新应用
优点:
- 对现有业务系统改造小,成本低。
- 使用新应用承载秒杀交易请求,灵活度高,不用过多考虑向后兼容问题。
缺点:
- 需要一定程度牺牲用户体验。
结论
基于成本和可行性考虑,采用方案二
五、架构设计
5.1 现有架构设计
- 前台应用直接承接用户访问、交易请求,无CDN服务。
- 前台应用接收到交易请求后,直接RPC同步请求中台应用
- 中台应用受到交易请求后,同步完成创建订单、支付、扣减商品数、完成交易等业务流程
- 前台应用接收到中台应用的处理结果,向用户展示交易商品的物流信息。
5.2 最新架构设计
5.2.1 架构设计一览图
5.2.2服务模块设计
1. 前端、客户端随机丢弃交易请求
- 根据用户查看商品详情页的次数,预估商品的热门程度,对不同商品设定不同的丢弃比率,设计字段:discard,取值为 [0, 100),作为商品属性。
- 前端、客户端,在用户提交交易请求时,生成 [0, 100] 范围内的随机数,discard < 随机数的订单直接丢弃,但向用户展示排队页面,排队10秒后直接显示交易失败。
2. 提供CDN服务
- 静态资源均保存在CDN服务中
- 前端展示的专门秒杀页面,除了「交易发起」请求外,用户的任何操作均不会请求到公司的微服务业务系统。
3. 开发专门的「秒杀应用」,提供熔断服务
- 秒杀应用直接承载前端、客户端的交易请求,授权通过的请求发往前台应用处理,授权拒绝的请求直接拦截,返回交易失败。
- 秒杀应用通过配置中心,实时获取最新配置。可配置对交易的丢弃比率,开发同事在秒杀时间段内,调整配置,保证发往业务系统的交易请求,TPS保持在 10000/s 以内。
- 秒杀应用无数据库,无状态,水平扩展后可成比例增加吞吐量。
4. 现有业务系统优化吞吐
- 前台、中台各应用,通过优化设计进而优化吞吐,有如下优化方式:
- 采用分库分表等水平拆分方式,横向扩展数据库,此时也可以大幅增加POD数了
- 静态数据缓存在Redis中,数据从Redis中取,保证不会读取数据库,后台定时任务更新缓存。「保证缓存定时更新且无缓存击穿」
- 分库分表策略:
- 按照商品拆分数据库与应用
- 按照用户id二次拆分数据库与应用
- 经过上述优化,至少可以将中台业务系统的短时间「1分钟内」系统未拒绝服务的最高TPS,由2000/s提升至4000/s
- 由于前台应用逻辑较简单,TPS可提升至10000/s,无需再优化。
- 由于木桶效应,业务系统整体的短时间「1分钟内」系统未拒绝服务的最高TPS,为4000/s
5. 异步队列
- 前台应用效率较高,此处仅优化中台应用即可。
- 前台应用将秒杀交易请求均发往 Kafka,中台应用通过 Kafka 消费消息,进行实际业务处理。
- 由于业务高峰时间段最多仅有半分钟 ~ 1分钟,中台应用在 2 分钟左右处理完全部交易也可以接受。
- Kafka 的 TPS 为数十 W/s,承载前台 5000/s ~ 10000/s 的TPS毫无压力。
- 经此优化,业务系统整体的短时间「1分钟内」系统未拒绝服务的最高TPS,可从 4000/s 提升至 10000/s
缺点:极端情况下,交易处理会较为缓慢。
6. 服务降级
- 秒杀开始前半小时到秒杀结束后的半小时,这个时间段内,部分服务降级
- 时间段内,不展示物流信息、不支持生成及展示发票,保证核心业务系统的稳定