秒杀系统设计思路
秒杀特性:
1. 商品个数有限
2. 时间分布集中
3. 流量超级大
整体方案:
1. 产品策略
a. 分离核心流程与其他可以延后处理的流程
b. 针对异常情况进行文案引导
2. 技术策略
a. 客户端、接入层、应用层、存储层 各层整个链路梳理。任何一个环节异常,都可能导致整体服务不可用。
b. 客户端重试策略的合理设计。固定超时时间+随机时间长,递增的超时时间,防止自我DDOS情况的发生。
c. 接入层是所有流量的入口,因此这里需要根据下游应用层处理能力,做好相应的限流。接入层可以使用 nginx, 性能有保障,配合 限流模块 实现。 其中包括 粗细管道。
c1. 提前把符合条件的uid ,加入cache, 在接入层快速鉴权,过滤不符合条件的用户。
c2. ip 频次 限制,设备检测,防止黑产,过滤无效用户。
c3. 针对秒杀商品总数有限,每个接入点放入的有效请求数超过总数后,直接返回结果。
d. 在应用层分离核心流程,在秒杀时,先处理核心流程,非关键流程延后处理,同时支持失败补偿机制,以及相应的幂等重试。
e. 存储层 缓存 redis 、消息队列 kafka, 最终记录写入mysql
f. 针对秒杀商品的库存,可以存入redis,更进一步可以再把这个总值提前拆分到N个节点上。
f1. 在redis中记录是否领取成功,用于用户实时查看结果。
g. 领取成功后,把对应的数据写入消息队列(kafka),kafka的写入性能在极限情况下,可以可以配置到非常高的,因此性能问题不必担心。
h. 异步消费队列数据,补齐之前的整个秒杀中未完成的逻辑。
3. 可用性
a. 静态资源的cdn部署,动态服务分地区部署,加速整个服务的响应时间。
b. 接入层、应用层 、存储层容灾,都至少部署在2个IDC,标准的做法是 2地3中心,或者3地5中心。
c. 存储层往往为了高性能,会选择异步复制的策略,因此如果由于故障进行主备切换,可能会造成备库数据不是最新的数据,造成超卖情况。如果要避免超卖,势必需要等主备同步完成,这将牺牲服务可用性。需要根据业务场景权衡。
d. 监控系统,包括服务基础监控,业务监控,秒杀数据的监控
e. 各种异常的预案,针对各种预案,提前写好执行方案。随时一键切换。
f. 秒杀相关的资源 与其他基础产品资源隔离,避免影响主要产品使用。这里资源包括 域名、接入层、应用层、缓存、数据库等资源。
4. 验证
a. 全流程压测。包括基本接口qps, 还要包括数据完整性验证。
b. 破坏性验证。比如断掉其中一个机房的全部服务,或者断掉集群中的任意节点。
c. 日志信息验证。如果某个环节发生失败,是否可以通过日志追踪到数据,保证最终一致性。
d. 异常预案验证。包括 切换的正确性验证,以及恢复时长的验证 。