您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

百万级用户抽奖系统,流量削峰架构设计方案分享

时间:2019-08-21 10:39:16  来源:  作者:
百万级用户抽奖系统,流量削峰架构设计方案分享

 

1、抽奖系统的背景引入

本文给大家分享一个之前经历过的抽奖系统的流量削峰架构设计方案。

抽奖、抢红包、秒杀,这类系统其实都有一些共同的特点,那就是在某个时间点会瞬间涌入大量的人来点击系统,给系统造成瞬间高于平时百倍、千倍甚至几十万倍的流量压力。

比如抽奖,有一种场景:某个网站或者App规定好了在某个时间点,所有人都可以参与抽奖,那么可能百万级的用户会蹲守在那个时间点,到时间大家一起参与这个抽奖。

抢红包,可能是某个电视节目上,突然说扫码可以抢红包,那么电视机前可能千万级的用户会瞬间一起打开手机扫码抢红包。

秒杀更是如此,所谓秒杀,意思是让大家都在电脑前等着,在某个时间突然就可以抢购某个限量的商品

比如某个手机平时卖5999,现在限量100台价格才2999,50%的折扣,可能百万级的用户就会蹲守在电脑前在比如凌晨12点一起点击按钮抢购这款手机。

类似的场景其实现在是很多的,那么本文就用一个抽奖系统举例,说说应对这种瞬时超高并发的流量,应该如何设计流量削峰的架构来应对,才能保证系统不会突然跨掉?

2、结合具体业务需求分析抽奖系统

假设现在有一个抽奖的业务场景,用户在某个时间可以参与抽奖,比如一共有1万个奖,奖品就是某个礼物。

然后参与抽奖的用户可能有几十万,一瞬间可能几十万请求涌入过来,接着瞬间其中1万人中奖了,剩余的人都是没中奖的。然后中奖的1万人的请求会联动调用礼品服务,完成这1万中奖人的礼品发放。

简单来说,需求场景就是如此,然而这里就有很多的地方值得优化了。

3、一个未经过优化的系统架构

先来看一个未经过任何优化的系统架构,简单来说就是有一个负载均衡的设备会把瞬间涌入的超高并发的流量转发到后台的抽奖服务上。

这个抽奖服务就是用普通的Tomcat来部署的,里面实现了具体的抽奖逻辑,假设刚开始最常规的抽奖逻辑是基于MySQL来实现的,接着就是基于Tomcat部署的礼品服务,抽奖服务如果发现中奖了需要调用礼品服务去发放礼品。

如下图所示:

百万级用户抽奖系统,流量削峰架构设计方案分享

 

4、负载均衡层的限流

4.1 防止用户重复抽奖

首先第一次在负载均衡层可以做的事情,就是防止重复抽奖。

我们可以在负载均衡设备中做一些配置,判断如果同一个用户在1分钟之内多次发送请求来进行抽奖,就认为是恶意重复抽奖,或者是他们自己写的脚本在刷奖,这种流量一律认为是无效流量,在负载均衡设备那个层次就给直接屏蔽掉。

举个例子,比如有几十万用户瞬间同时抽奖,最多其实也就几十万请求而已,但是如果有人重复抽奖或者是写脚本刷奖,那可能瞬间涌入的是几百万的请求,就不是几十万的请求了,所以这里就可以把无效流量给拦截掉。

如下图所示:

百万级用户抽奖系统,流量削峰架构设计方案分享

 

4.2 全部开奖后暴力拦截流量

其实秒杀、抢红包、抽奖,这类系统有一个共同的特点,那就是假设有50万请求涌入进来,可能前5万请求就直接把事儿干完了,甚至是前500请求就把事儿干完了,后续的几十万流量是无效的,不需要让他们进入后台系统执行业务逻辑了。

什么意思呢?

举个例子,秒杀商品,假设有50万人抢一个特价手机,人家就准备了100台手机,那么50万请求瞬间涌入,其实前500个请求就把手机抢完了,后续的几十万请求没必要让他转发到Tomcat服务中去执行秒杀业务逻辑了,不是吗?

抽奖、红包都是一样的 ,可能50万请求涌入,但是前1万个请求就把奖品都抽完了,或者把红包都抢完了,后续的流量其实已经不需要放到Tomcat抽奖服务上去了,直接暴力拦截返回抽奖结束就可以了。

这样的话,其实在负载均衡这一层(可以考虑用Nginx之类的来实现)就可以拦截掉99%的无效流量。

所以必须让抽奖服务跟负载均衡之间有一个状态共享的机制。

就是说抽奖服务一旦全部开奖完毕,直接更新一个共享状态。然后负载均衡感知到了之后,后续请求全部拦截掉返回一个抽奖结束的标识就可以了。

这么做可能就会做到50万人一起请求,结果就可能2万请求到了后台的Tomcat抽奖服务中,48万请求直接拦截掉了。

我们可以基于redis来实现这种共享抽奖状态,它非常轻量级,很适合两个层次的系统的共享访问。

当然其实用ZooKeeper也是可以的,在负载均衡层可以基于zk客户端监听某个znode节点状态。一旦抽奖结束,抽奖服务更新zk状态,负载均衡层会感知到。

下图展示了上述所说的过程:

百万级用户抽奖系统,流量削峰架构设计方案分享

 

5、Tomcat线程数量的优化

其次就是对于线上生产环境的Tomcat,有一个至关重要的参数是需要根据自己的情况调节好的,那就是他的工作线程数量。

众所周知,对于进入Tomcat的每个请求,其实都会交给一个独立的工作线程来进行处理,那么Tomcat有多少线程,就决定了并发请求处理的能力。

但是这个线程数量是需要经过压测来进行判断的,因为每个线程都会处理一个请求,这个请求又需要访问数据库之类的外部系统,所以不是每个系统的参数都可以一样的,需要自己对系统进行压测。

但是给一个经验值的话,Tomcat的线程数量不宜过多。因为线程过多,普通虚拟机的CPU是扛不住的,反而会导致机器CPU负载过高,最终崩溃。

同时,Tomcat的线程数量也不宜太少,因为如果就100个线程,那么会导致无法充分利用Tomcat的线程资源和机器的CPU资源。

所以一般来说,Tomcat线程数量在200~500之间都是可以的,但是具体多少需要自己压测一下,不断的调节参数,看具体的CPU负载以及线程执行请求的一个效率。

在CPU负载尚可,以及请求执行性能正常的情况下,尽可能提高一些线程数量。

但是如果到一个临界值,发现机器负载过高,而且线程处理请求的速度开始下降,说明这台机扛不住这么多线程并发执行处理请求了,此时就不能继续上调线程数量了。

百万级用户抽奖系统,流量削峰架构设计方案分享

 

6、基于Redis实现抽奖业务逻辑

现在问题又来了,虽然在负载均衡那个层面,已经把比如50万流量中的48万都拦截掉了,但是可能还是会有2万流量进入抽奖服务

此时抽奖服务自然是可以多机器来部署的,比如假设一台Tomcat可以抗500请求,那么2万并发就是40台机器。

如果你是基于云平台来部署系统的,搞活动临时租用一批机器就可以了,活动结束了机器立马可以释放掉,现在云平台都很方便。

但是有个问题,你的数据库MySQL能抗住2万的并发请求吗?

如果你基于MySQL来实现核心的抽奖业务逻辑,40个Tomcat部署的抽奖服务频繁对MySQL进行增删改查,这一个MySQL实例也是很难抗住的。

所以此时还得把MySQL给替换成Redis,通常这种场景下,建议是基于Redis来实现核心的业务逻辑。

Redis单机抗2万并发那是很轻松的一件事情,所以在这里又需要做进一步的优化。如下图:

百万级用户抽奖系统,流量削峰架构设计方案分享

 

7、发放礼品环节进行限流削峰

接着问题又来了,假设抽奖服务在2万请求中有1万请求抽中了奖品,那么势必会造成抽奖服务对礼品服务调用1万次。

礼品服务假设也是优化后的Tomcat,可以抗500并发,难道礼品服务也要去部署20台机器吗?

其实这是没必要的,因为抽奖之后完全可以让礼品服务在后台慢慢的把中奖的礼品给发放出去,不需要一下子就立马对1万个请求完成礼品的发放逻辑。

所以这里可以在抽奖服务和礼品服务之间,引入消息中间件,进行限流削峰

也就是说,抽奖服务把中奖信息发送到MQ,然后礼品服务假设就部署两个Tomcat,慢慢的从MQ中消费中奖消息,然后慢慢完成1完礼品的发放就可以了。

假设两个礼品服务实例每秒可以完成100个礼品的发放,那么1万个礼品也就是延迟100秒发放完毕罢了。

也就是你抽奖之后,可能过了一两分钟,会看到自己的礼品发放的一些物流配送的进度之类的。

而且礼品服务可能需要在MySQL数据库中做很多增删改查的操作,比如插入中奖纪录,然后进行礼品发货等等。

此时因为礼品服务就2个Tomcat实例,所以对MySQL的并发读写不会太高,那么数据库层面也是可以抗住的。

整个过程,如下图所示:

百万级用户抽奖系统,流量削峰架构设计方案分享

 

8、系统架构设计总结

其实对于商品秒杀、抽奖活动、抢红包类的系统而言,架构设计的思路很多都是类似的,核心思路都是对于这种瞬时超高流量的系统,尽可能在负载均衡层就把99%的无效流量拦截掉

然后在1%的流量进入核心业务服务后,此时每秒并发还是可能会上万,那么可以基于Redis实现核心业务逻辑 ,抗住上万并发。

最后对于类似秒杀商品发货、抽奖商品发货、红包资金转账之类的非常耗时的操作,完全可以基于MQ来限流削峰,后台有一个服务慢慢执行即可。



Tags:抽奖系统架构   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1、抽奖系统的背景引入本文给大家分享一个之前经历过的抽奖系统的流量削峰架构的设计方案。抽奖、抢红包、秒杀,这类系统其实都有一些共同的特点,那就是在某个时间点会瞬间涌...【详细内容】
2019-08-21  Tags: 抽奖系统架构  点击:(270)  评论:(0)  加入收藏
▌简易百科推荐
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(5)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(7)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(10)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(9)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(21)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(17)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(23)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  大数据架构师    Tags:Netty   点击:(17)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  人月聊IT    Tags:架构   点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  GreekDataGuy  CSDN  Tags:单体应用   点击:(35)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条