如何设计一个“稳、准、快”的秒杀系统

秒杀在互联网电商中很常见。比如,淘宝“双十一”,你在和上万人一起抢购一件性价比超高的衣服?春运时我们都会去 12306 订购火车票。在这些高并发场景下都需要保证高性能和高可用。

先思考一下,如果由你来设计高并发秒杀,怎么保证衣服不会超卖?以前在抢票时经常遇到页面打不开的情况,让你来设计 12306 系统,如何保证在千万人访问的同时也能支持正常抢票呢?

「系统设计」如何设计一个“稳、准、快”的秒杀系统


其实,秒杀本质上是要解决两个问题 并发读(减少直接读库),并发写(层层设卡- 保db)。前辈大牛们总结出了“三五”原则(观点参考自许令波《如何设计一个秒杀系统》)。

一、宏观架构上要遵循“稳、准、快” 3大原则

1.稳:指高可用

做好降级限流措施,防止最坏情况发生。要设计好兜底方案,保证不掉链子,秒杀活动顺利完成。

2.准:指一致性

商品、订单要最终一致性。成交多一台少一台都不行。

3.快:指高性能

整个请求链路上都要做协同的优化,包括:

a. 浏览器优化技术:合理布局,页面缓存,减少http请求数,页面压缩,减少 cookie 传输

b. 设计数据的动静分离方案(秒杀时不需要刷新整个页面,而只需要点击抢购按钮)

c. 热点的发现与隔离(最关键的详情和交易系统增加本地缓存,提前缓存秒杀商品的信息)

d. 请求的削峰与分层过滤(比如秒杀答题提交,消息队列缓冲瞬时流量或线程池加锁等待)

e. 服务端的极致优化(比如部分缓存前置在nginx层,业务代码优化,可能需要牺牲通用性)

二、微观架构上要遵循“4 要 1 不要” 5个原则

1. 数据要尽量少

数据在网络上传输需要时间,服务器在写网络时通常都要做压缩和字符编码,这些都非常消耗CPU

系统依赖的数据能少就少。因为这些数据一般是和后台服务(涉及数据的序列化和反序列化,增加延时)以及数据库(容易成为一个瓶颈)打交道的。

2. 请求数要尽量少

秒杀页面做好缓存(CSS/JavaScript、图片),减少http请求数,尽量减少“额外请求”

建立连接要做三次握手,一些请求(例如 JavaScript)还需要串行加载等。另外,如果不同请求的域名不一样的话,还涉及这些域名的 DNS 解析,可能会耗时更久。

3. 路径要尽量短

缩短请求路径不仅可以增加可用性,同样可以有效提升性能(减少中间节点可以减少数据的序列化与反序列化),并减少延时(可以减少网络传输耗时)

要缩短访问路径有一种办法,就是多个相互强依赖的应用合并部署在一起,把远程过程调用(RPC)变成 JVM 内部之间的方法调用。

4. 依赖要尽量少

依赖一般分为“强”依赖(比如秒杀页面必须强依赖商品信息、用户信息)和“弱”依赖(优惠券、成交列表)。“弱”依赖属于可有可无的信息,在紧急情况下就可以抛弃掉。

要减少依赖,我们可以给系统进行分级,防止重要的系统被不重要的系统拖垮。避免最重要的系统强依赖不那么重要的系统。

例如支付系统不应该强依赖优惠券,在极端情况下可以把优惠券给降级,防止支付系统被优惠券系统给拖垮。

5. 不要有单点

架构上单点是大忌(单点意味着没有备份,风险不可控),设计分布式系统最重要的原则就是“消除单点”。

应用无状态化是有效避免单点的一种方式。但有例外,存储服务本身很难无状态化,因为数据要存储在磁盘上,本身就要和机器绑定,这种场景要冗余多个备份来解决单点问题。



架构是一门平衡的艺术,最好的架构离不开特定的业务场景,抛开业务谈架构一切都将是空谈。如何优化,优化到什么程度需要依量(流量、体量)而行。

秒杀系统演进也是一个渐进的过程,并非一蹴而就,你在工作中积累了哪些经验又踩到了哪些坑呢?欢迎留言讨论。

声明:本站发布的内容以原创、转载、分享网络内容为主,如有侵权,请联系电话:021-51697771-8029,邮箱:mj@cndns.com ,我们将会在第一时间删除。文章观点不代表本站立场,如需处理请联系我们。

热门TAG

热门视频