如何设计一个秒杀系统(下)

简介: 这里我们讲解最后一部分

高可用


盯过秒杀流量监控的话,会发现它不是一条蜿蜒而起的曲线,而是一条挺拔的直线,这是因为秒杀请求高度集中于某一特定的时间点。这样一来就会造成一个特别高的零点峰值,而对资源的消耗也几乎是瞬时的。所以秒杀系统的可用性保护是不可或缺的。


1 流量削峰


对于秒杀的目标场景,最终能够抢到商品的人数是固定的,无论 100 人和 10000 人参加结果都是一样的,即有效请求额度是有限的。并发度越高,无效请求也就越多。但秒杀作为一种商业营销手段,活动开始之前是希望有更多的人来刷页面,只是真正开始后,秒杀请求不是越多越好。因此系统可以设计一些规则,人为的延缓秒杀请求,甚至可以过滤掉一些无效请求。


1.1 答题


早期秒杀只是简单的点击秒杀按钮,后来才增加了答题。为什么要增加答题呢?主要是通过提升购买的复杂度,达到两个目的:


防止作弊。早期秒杀器比较猖獗,存在恶意买家或竞争对手使用秒杀器扫货的情况,商家没有达到营销的目的,所以增加答题来进行限制

延缓请求。零点流量的起效时间是毫秒级的,答题可以人为拉长峰值下单的时长,由之前的 <1s 延长到 <10s。这个时间对于服务端非常重要,会大大减轻高峰期并发压力;另外,由于请求具有先后顺序,答题后置的请求到来时可能已经没有库存了,因此根本无法下单,此阶段落到数据层真正的写也就非常有限了, 需要注意的是,答题除了做正确性验证,还需要对提交时间做验证,比如<1s 人为操作的可能性就很小,可以进一步防止机器答题的情况。

答题目前已经使用的非常普遍了,本质是通过在入口层削减流量,从而让系统更好地支撑瞬时峰值。


1.2 排队


最为常见的削峰方案是使用消息队列,通过把同步的直接调用转换成异步的间接推送缓冲瞬时流量。除了消息队列,类似的排队方案还有很多,例如:


线程池加锁等待

本地内存蓄洪等待

本地文件序列化写,再顺序读

排队方式的弊端也是显而易见的,主要有两点:


请求积压。流量高峰如果长时间持续,达到了队列的水位上限,队列同样会被压垮,这样虽然保护了下游系统,但是和请求直接丢弃也没多大区别

用户体验。异步推送的实时性和有序性自然是比不上同步调用的,由此可能出现请求先发后至的情况,影响部分敏感用户的购物体验

排队本质是在业务层将一步操作转变成两步操作,从而起到缓冲的作用,但鉴于此种方式的弊端,最终还是要基于业务量级和秒杀场景做出妥协和平衡。


1.3 过滤


过滤的核心结构在于分层,通过在不同层次过滤掉无效请求,达到数据读写的精准触发。常见的过滤主要有以下几层:


1、读限流:对读请求做限流保护,将超出系统承载能力的请求过滤掉

2、读缓存:对读请求做数据缓存,将重复的请求过滤掉

3、写限流:对写请求做限流保护,将超出系统承载能力的请求过滤掉

4、写校验:对写请求做一致性校验,只保留最终的有效数据


过滤的核心目的是通过减少无效请求的数据IO保障有效请求的IO性能。


1.4 小结


系统可以通过入口层的答题、业务层的排队、数据层的过滤达到流量削峰的目的,本质是在寻求商业诉求与架构性能之间的平衡。另外,新的削峰手段也层出不穷,以业务切入居多,比如零点大促时同步发放优惠券或发起抽奖活动,将一部分流量分散到其他系统,这样也能起到削峰的作用。


2 Plan B(兜底方案设计)


当一个系统面临持续的高峰流量时,其实是很难单靠自身调整来恢复状态的,日常运维没有人能够预估所有情况,意外总是无法避免。尤其在秒杀这一场景下,为了保证系统的高可用,必须设计一个 Plan B 方案来进行兜底。


高可用建设,其实是一个系统工程,贯穿在系统建设的整个生命周期


1.png


具体来说,系统的高可用建设涉及架构阶段、编码阶段、测试阶段、发布阶段、运行阶段,以及故障发生时,逐一进行分析:


架构阶段:考虑系统的可扩展性和容错性,避免出现单点问题。例如多地单元化部署,即使某个IDC甚至地市出现故障,仍不会影响系统运转


编码阶段:保证代码的健壮性,例如RPC调用时,设置合理的超时退出机制,防止被其他系统拖垮,同时也要对无法预料的返回错误进行默认的处理


测试阶段:保证CI的覆盖度以及Sonar的容错率,对基础质量进行二次校验,并定期产出整体质量的趋势报告


发布阶段:系统部署最容易暴露错误,因此要有前置的checklist模版、中置的上下游周知机制以及后置的回滚机制


运行阶段:系统多数时间处于运行态,最重要的是运行时的实时监控,及时发现问题、准确报警并能提供详细数据,以便排查问题


故障发生:首要目标是及时止损,防止影响面扩大,然后定位原因、解决问题,最后恢复服务


对于日常运维而言,高可用更多是针对运行阶段而言的,此阶段需要额外进行加强建设,主要有以下几种手段:


预防:建立常态压测体系,定期对服务进行单点压测以及全链路压测,摸排水位


管控:做好线上运行的降级、限流和熔断保护。需要注意的是,无论是限流、降级还是熔断,对业务都是有损的,所以在进行操作前,一定要和上下游业务确认好再进行。就拿限流来说,哪些业务可以限、什么情况下限、限流时间多长、什么情况下进行恢复,都要和业务方反复确认


监控:建立性能基线,记录性能的变化趋势;建立报警体系,发现问题及时预警


恢复:遇到故障能够及时止损,并提供快速的数据订正工具,不一定要好,但一定要有

在系统建设的整个生命周期中,每个环节中都可能犯错,甚至有些环节犯的错,后面是无法弥补的或者成本极高的。所以高可用是一个系统工程,必须放到整个生命周期中进行全面考虑。同时,考虑到服务的增长性,高可用更需要长期规划并进行体系化建设。


3 总结一下


高可用其实是在说 “稳定性”,稳定性是一个平时不重要,但出了问题就要命的事情,然而它的落地又是一个问题——平时业务发展良好,稳定性建设就会降级给业务让路。解决这个问题必须在组织上有所保障,比如让业务负责人背上稳定性绩效指标,同时在部门中建立稳定性建设小组,小组成员由每条线的核心力量兼任,绩效由稳定性负责人来打分,这样就可以把体系化的建设任务落实到具体的业务系统中


个人总结


一个秒杀系统的设计,可以根据不同级别的流量,由简单到复杂打造出不同的架构,本质是各方面的取舍和权衡。当然,你可能注意到,本文并没有涉及具体的选型方案,因为这些对于架构来说并不重要,作为架构师,应该时刻提醒自己主线是什么。


同时也在这里抽象、提炼一下,主要是个人对于秒杀设计的提纲式整理。


2.png




相关文章
|
2月前
|
缓存 前端开发 NoSQL
如何设计一个秒杀系统?
本文详细介绍了秒杀系统的原理与设计方法,包括高性能、一致性、高可用性和可扩展性等方面的要求。文中通过前端和后端的设计方案,探讨了如何实现秒杀系统的高并发处理,例如页面静态化、限流、降级策略及缓存优化等。此外,还分享了实际项目中的库存系统架构设计经验,并提供了面试中如何回答此类问题的建议。
157 2
|
2月前
|
缓存 NoSQL 应用服务中间件
【开发系列】秒杀系统的设计
【开发系列】秒杀系统的设计
|
缓存 NoSQL 数据库
【高并发】秒杀系统设计思路
【高并发】秒杀系统设计思路
216 0
|
消息中间件 缓存 NoSQL
如何设计一个秒杀系统???
如何设计一个秒杀系统???
186 0
|
消息中间件 缓存 安全
秒杀系统(1)——秒杀功能设计理念
秒杀系统(1)——秒杀功能设计理念
185 0
|
消息中间件 缓存 JavaScript
如何设计一个秒杀系统
如何设计一个秒杀系统
|
缓存 NoSQL 安全
秒杀系统的设计思路
你好看官,里面请!今天笔者讲的是秒杀系统的设计思路。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
434 2
|
数据采集 域名解析 缓存
设计一个秒杀系统架构
对于秒杀架构的设计,需要遵循以下个原则: 东西不能超卖、 下单成功的订单数据不能丢失、 服务器和数据库不能挂 尽量不让机器人抢走 整体的思路 秒杀架构的设计方案就是一个不断过滤请求的过程,从系统架构层面来说,秒杀系统的分层思路如下。
179 0
|
数据采集 缓存 前端开发
如何设计一个秒杀系统(上)
秒杀大家都不陌生。自2011年首次出现以来,无论是双十一购物还是 12306 抢票,秒杀场景已随处可见。简单来说,秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。从架构视角来看,秒杀系统本质是一个高性能、高一致、高可用的三高系统。而打造并维护一个超大流量的秒杀系统需要进行哪些关注,就是本文讨论的话题。
546 0
如何设计一个秒杀系统(上)
|
缓存 监控 NoSQL
秒杀系统
秒杀能够以极小的经费撬动巨大的流量,虽然会带来一定的口碑损失,但因为极具性价比,所以经常被运营同学使用。本文介绍如何设计一款能够支撑60W QPS的秒杀系统,希望能够帮助到大家。