写点什么

由微视春节集卡瓜分活动,看高可用秒杀系统的架构设计

  • 2020-04-18
  • 本文字数:3026 字

    阅读完需:约 10 分钟

由微视春节集卡瓜分活动,看高可用秒杀系统的架构设计

导语 | 微视春节项目中的集卡瓜分活动,是一个典型流量洪峰下的秒杀场景,本文作者参与其中,对高可用秒杀系统的架构设计做了一些思考和总结。(流量洪峰所带来的一系列挑战,足以激发每位程序员的斗志。云加社区将推出「高可用架构之流量洪峰」系列内容,欢迎关注)。

一、背景简介

如今的互联网已经在海量服务领域有了很成熟的理论,有很多在流量洪峰下的实践。而微视春节项目中的集卡瓜分活动,主要环节包括发卡、集卡、瓜分等流程,涉及到高并发、降级预案等,是一个典型流量洪峰下的秒杀场景。我有幸参与其中,从 0 到 1 完整践行了海量服务。本文是对高可用秒杀系统的架构设计的一些思考,希望对读者有所帮助。


二、秒杀系统剖析

1. 秒杀系统面临的难点

(1)如何保证友好的用户体验?

用户不能接受破窗的体验,例如:系统超时、系统错误的提示,或者直接 404 页面。

(2)如何应对瞬时高并发流量的挑战?

木桶短板理论,整个系统的瓶颈往往都在 DB,如何设计出高并发、高可用系统?

2. 如何设计秒杀系统?

(1)典型的互联网业务结构

下图展示了一个典型的互联网业务结构抽象图,用户完成一个写操作,一般会通过接入层和逻辑层,这里的服务都是无状态,可以通过平行拓展去解决高并发的问题;到了 DB 层,必须要落到介质中,可以是磁盘/ssd/内存,如果出现 key 的冲突,会有一些并发控制技术,例如 cas/加锁/串行排队等。


(2)直筒型架构设计

直筒型架构设计,指的是用户请求 1:1 的洞穿到 DB 层,如下图所示。在比较简单的业务中,才会采用这个模型。随着业务规模复杂度上来,一定会有 DB 和逻辑层分离、逻辑层和接入层分离。


(3)漏斗型架构设计

漏斗型架构设计,指的是,用户的请求,从客户端到 DB 层,层层递减,递减的程度视业务而定。例如当 10 万人去抢 1 个物品时,DB 层的请求在个位数量级,对于秒杀系统来讲,漏斗型架构设计就是比较理想的模型,如下图所示。



漏斗型的架构设计,是高并发的基础,能够做到:


  • 及早发现,及早拒绝

  • Fast Fail

  • 前端保护后端

3. 如何实现漏斗型系统?

漏斗型系统需要从产品策略/客户端/接入层/逻辑层/DB 层全方位立体的设计。


(1)产品策略

  • 轻重逻辑分离,以秒杀为例,将抢到和到账分开;

  • 抢到,是比较轻的操作,库存扣成功后,就可以成功了。

  • 到账,是比较重的操作,需要涉及到到事务操作。

  • 用户分流,以整点秒杀活动为例,在 1 分钟内,陆续对用户放开入口,将所有用户请求打散在 60s 内,请求就可以降一个数量级。

  • 页面简化,在秒杀开始的时候,需要简化页面展示,该时刻只保留和秒杀相关的功能。例如,秒杀开始的时候,页面可以不展示推荐的商品。

(2)客户端

  • 重试策略非常关键,如果用户秒杀失败了,频繁重试,会加剧后端的雪崩。如何重试呢?根据后端返回码的约定,有两种方法:

  • 不允许重试错误,此时 UI 和文案都需要有一个提示。同时不允许重试;

  • 可重试错误,需要策略重试,例如二进制退避法。同时文案和 UI 需要提示。

  • UI 和文案,秒杀开始前后,用户的所有异常都需要有精心设计的 UI 和文案提示。例如:【当前活动太火爆,请稍后再重试】【你的货物堵在路上,请稍后查看】等。

  • 前端随机丢弃请求可以作为降级方案,当用户流量远远大于系统容量时,人工下发随机丢弃标记,用户本地客户端开始随机丢弃请求。

(3)接入层

  • 所有请求需要鉴权,校验合法身份。

  • 如果是长链接的服务,鉴权粒度可以在 session 级别;如果是短链接业务,需要应对这种高并发流量,例如 cache 等。

  • 根据后端系统容量,需要一个全局的限流功能,通常有两种做法:

  • 设置好 N 后,动态获取机器部署情况 M,然后下发单机限流值 N/M。要求请求均匀访问,部署机器统一。

  • 维护全局 key,以时间戳建 key。有热 key 问题,可以通过增加更细粒度的 key 或者定时更新 key 的方法。

  • 对于单用户/单 IP 需要频控,主要是防黑产和恶意用户。如果秒杀是有条件的,例如需要完成 xxx 任务,解锁资格,对于获得资格的步骤,可以进行安全扫描,识别出黑产和恶意用户。

(4)逻辑层

  • 逻辑层首先应该进入校验逻辑,例如参数的合法性,是否有资格,如果失败的用户,快速返回,避免请求洞穿到 DB。

  • 异步补单,对于已经扣除秒杀资格的用户,如果发货失败后,通常的两种做法是:

  • 事务回滚,回滚本次行为,提示用户重试。这个代价特别大,而且用户重试和前面的重试策略结合的话,用户体验也不大流畅。

  • 异步重做,记录本次用户的 log,提示用户【稍后查看,正在发货中】,后台在峰值过后,启动异步补单。需要服务支持幂等。

  • 对于发货的库存,需要处理热 key。通常的做法是,维护多个 key,每个用户固定去某个查询库存。对于大量人抢红包的场景,可以提前分配。

(5)存储层

对于业务模型而言,对于 DB 的要求需要保证几个原则:


  • 可靠性

  • 主备:主备能互相切换,一般要求在同城跨机房。

  • 异地容灾:当一地异常,数据能恢复,异地能选主。

  • 数据需要持久化到磁盘,或者更冷的设备。

  • 一致性

  • 对于秒杀而言,需要严格的一致性,一般要求主备严格的一致。

三、微视春节集卡瓜分活动实践

1. 用户体验流程

微视集卡瓜分项目属于微视春节项目之一。用户的体验流程如下:


2. 架构设计图

微视集卡瓜分项目的架构设计如下图所示。



  • 客户端主要是微视主 APP 和 H5 页面,主 App 是入口,H5 页面是集卡活动页面和瓜分页面。

  • 逻辑部分主要分为:发卡来源、集卡模块、奖品模块,发卡来源主要是任务模块;集卡模块主要由活动模块和集卡模块组成。瓜分部分主要在活动控制层。

  • 奖品模块主要是发钱和其他奖品。

3. 瓜分降级预案

为了做好瓜分时刻的高并发,对整个系统需要保证两个重要的事情:


  • 全链路梳理,包括调用链的合理性和时延设置。

  • 降级服务预案分析,提升系统的鲁棒性。


针对瓜分全链路调用分析时,需要特别说明的几点:


  • 时延很重要,需要全链路分析。不但可以提高吞吐量,而且可以快速暴露系统的瓶颈。

  • 峰值时刻,补单逻辑需要关闭,避免加剧雪崩。


我们的降级预案大概如下:


(1)一级预案(瓜分时刻前后 5 分钟自动进入)


  • 入口处 1 分钟内陆续放开入口倒计时,未登录用户不弹入口。

  • 主会场排队,进主会场 20wqps,超过了进入排队,由接入层频控控制。

  • 拉取资格接口排队,拉取资格接口 20wqps,超过了进入排队,由接入层频控控制。

  • 抢红包排队,抢红包 20wqps,超过了进入排队,由接入层频控控制。

  • 红包到账排队,如果资格扣除成功,现金发放失败,进入排队,24 小时内到账。异步补单。

  • 入口处调用后端非关键 rpc:ParticipateStatus,手动关闭。

  • 异步补单逻辑关闭。


(2)二级预案,后端随机丢请求,接入层频控失效或者下游服务过载,手动开启。


(3)三级预案,前端随机丢请求,后端服务过载或者宕机进入,手动开启。


综上,整个瓜分时刻体验如下所示:



最后,对应漏斗模型,总结下这次活动的实践。


四、关于架构师成长的几点思考

  • 建立自己关于整个技术领域的知识图谱很重要,例如从访问一个网站开始,都经历了哪些技术点?从工作中学习,对每个技术点刨根问底,把工作中的积累放到自己的知识图谱中。

  • 找机会总结、分享,把知识图谱分享给别人,一方面可以加深熟悉自己的知识图谱,另一方面可以和他人技术交流,提高自己分享表达的能力,也是对自身抽象能力的锻炼。

  • 随着知识图谱的建立,熟悉互联网技术的分布式问题解决方案,可以进一步在自己业务上梳理和抽象业务模型,积累自身领域经验。

  • 在业务发展和代码重构中,去体验和验证自己的领域经验。再把领域经验横向对比其他业务模型。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接


https://mp.weixin.qq.com/s/-M9PzF0O9d8zbJnsIFN8WQ


2020-04-18 10:063720

评论

发布
暂无评论
发现更多内容

Flutter 开发一个常用的登录界面

岛上码农

ios 移动端开发 3月月更 flutter开发 安卓开发

被动防御→积极防御,系统稳定性保障思路启发

TakinTalks稳定性社区

Hoo虎符研究院 ∣ 投资前沿——STARKNET 生态一览 (2022.3.18)

区块链前沿News

虎符研究院

Apache DolphinScheduler&ShenYu(Incubating)联合 Meetup,暖春 3 月与你相约!

白鲸开源

大数据 开源 工作流调度 Apache DolphinScheduler

程序员的工作就只有写代码么?

程序员鱼皮

经验

失败案例之安全抓包测试

网络安全学海

网络安全 信息安全 渗透测试 安全漏洞 网络抓包

2022年中国可穿戴医疗设备发展洞察

易观分析

可穿戴医疗设备

达观数据CTO 纪达麒:基于阿里云计算底座,打造智能办公机器人

阿里云弹性计算

机器人 神龙架构 智能办公

2022最新IntellJ IDEA的mall开发部署文档

北极的大企鹅

开源 部署与维护 开发者, MAll

第三空间娱乐体验重构:AITO 问界 M5雕刻的七宝楼台

脑极体

Rust的迭代器

Shine

rust 迭代器

JVM自定义类加载器在代码扩展性的实践

Java工程师

JVM 代码 类加载器 实践 #java

毕业总结

Geek_93ffb0

「架构实战营」

微博评论高性能高可用计算架构设计

Geek_36cc7c

如何用建木CI实现前端代码自动格式化

Jianmu

前端 代码管理 格式化 prettier 建木CI

Linux之alias命令

入门小站

Linux

国际自主智能机器人大赛强势来袭,NAACL同声传译任务等你来战

百度大脑

Redis Pipeline原来是这么用的

Java工程师

数据库 程序员 代码 pipeline redis'

Linux运维技术之Linux云计算架构

学神来啦

Linux 架构 运维 linux云计算

好评不断的文化纪录片《中国》,背后的“剪刀手”竟是它?

百度大脑

SpringBoot接入轻量级分布式日志框架(GrayLog)

Java工程师

程序员 分布式 Web spring-boot

重新刷新你对Redis集群的理解

Java工程师

数据库 复制 数据共享 集群 redis'

区块链正在塑造医疗保健生态系统!

CECBC

低版本skywalking与LinkAgent不兼容怎么办?记一次详细的解决过程

TakinTalks稳定性社区

Docker 配置国内加速镜像

信号量

Docker Linxu

Apache DolphinScheduler&ShenYu(Incubating)联合 Meetup,暖春 3 月与你相约!

大数据 开源 工作流调度 Apache DolphinScheduler

网易会议开源之桌面端篇

网易云信

开源

网易数帆Curve加入PolarDB开源数据库社区

阿里云数据库开源

数据库 阿里云 开源数据库 polarDB

调查:区块链游戏玩家将玩NFT游戏视为一份潜在的全职工作

CECBC

Flash退出历史舞台后,Web端3D会迎来怎样的发展?

Orillusion

WebGL 3D渲染 3D模型 Flash webgpu

北京大学董豪老师解密人工智能开发工具的过去与未来

OpenI启智社区

人工智能 开发工具 启智社区 北京大学

由微视春节集卡瓜分活动,看高可用秒杀系统的架构设计_架构_云加社区_InfoQ精选文章