抢红包、秒杀等营销手段现在越来越流行了,而这种活动却带给IT攻城狮们巨大的挑战。抢红包系统从前端看起来都是很简单的,但实际上对应的后端系统却非常复杂,因为瞬时高并发所带来的问题将整个系统架构的复杂度提升了几个数量级。
笔者所在的驻云科技就参与了春晚支付宝老庙黄金新春抢红包活动系统的建设和护航工作。在这里跟大家做个分享,一起探讨如何利用云计算技术来在短时间内构建强大且具备灵活扩展性的架构。
一、 架构需求调研
抢红包系统的逻辑一般都比较简单,用户在一个页面上点击,加上简单的交互,将请求发送至服务端,由服务端接受请求并根据业务需求处理后返回红包结果给客户端。那么在需求调研阶段就必须了解清楚几个信息:
1. 并发峰值的估算
知道了并发峰值,才好来评估带宽、负载均衡、服务器数量等。那么怎么来预估峰值?一般根据活动预计参与的人数和参与时段可以来做简单估算。例如预计会有 1000万人参加,共1个小时,那么平均每秒并发就是 2800左右,由于一般在活动开始时压力会比较大,系统最大峰值一般是平均值的5-10倍左右。当然具体的要看活动形式来估算。在本次春晚活动预估的每秒并发为10万左右。
2. 活动参与形式及交互形式
活动形式的设计会直接影响到系统的架构设计,例如是在客户端完成一系列交互后发送一次请求至服务端,还是每次交互都要连接服务端。交互都在客户端完成实现比较简单,对服务端压力也最小,但是交互形式比较固定。
在今年的春晚红包活动中,由于并发压力较大,同时业务需求不复杂,因此交互基本都放在客户端来完成。
大致流程如下:用户点击支付宝咻一咻,会随机出现老庙红包界面,然后点击打开红包则由服务端随机返回一个不同额度的优惠券,然后用户通过优惠券id进行实体店或者网店的消费。效果图如下:
3. 活动数据需求
大部分活动在进行中或者结束后都需要统计活动情况信息,例如每个时段的用户数、访问量、业务量等等。因此在系统设计时就需要考虑到整个系统的访问情况和用户行为数据以何种形式和方式保存下来。数据库、日志、缓存等手段都是常用的,但是在在高并发情况下,日志对性能的影响也都非常大。以写日志文件为例,单机数千并发频繁的磁盘IO会导致严重的响应问题,很多类似系统都发生过看起来并不起眼的日志文件是性能瓶颈的罪魁祸首。
二、 架构设计
正确的架构是系统成功的基石,那么我们就要从业务层面来分析下抢红包活动的系统架构有哪些典型特点?
- 恐怖的峰值并发,并发/TPS/QPS一般都是在数万甚至数十万。(双11天猫的交易大约在10万笔/秒);
- 时效性非常强, 活动一般都在固定的时间或者事件触发,错过了就没有了;
- 稳定性要求高,只许成功不许失败。正是由于活动的时效性很强,比如春晚直播的那一两分钟,如果系统出现哪怕10秒的故障对整个活动的效果就会大打折扣;
- 性能要求高,不能慢。高并发时往往带来的就是对请求的响应时间变长,但是在促销情况下过长的延时用户是无法忍受的;
- 系统压力未知性,访问量,用户量,并发量的不可预测。在活动前一般都会做一定的预测,但是不确定性非常大,可能由于某一个特殊事件,系统访问量就会远远超于预期。因此健壮的架构必须能够承担超额的访问量,并且要做到足够弹性,当业务压力增长时可以随时扩容。
了解了这些典型特点,架构设计就要正式开始了。
1. 基础设施架构选型
整个系统选用阿里云作为基础架构。那么为什么用云而不是传统的硬件或者虚拟化IT架构来实现呢?并不是因为现在云计算流行而选云,而是因为只有云计算才能胜任,为什么?
- 资源弹性,计算资源、网络资源需要多少随时就可以获取和扩展。
- 快速交付能力,整个项目从开发到上线只有20天时间,不用云估计很难完成。
- 成本,由于整个活动只持续春节期间15天左右的时间,较低的综合成本是必须考虑的。
基于这些因素考虑,我们来分别分析下具体架构:
2. 应用架构设计
采用典型的三层架构,接入层—负载均衡SLB,应用层—虚拟机ECS,数据层-数据库RDS。
- 接入层使用负载均衡SLB的原因很简单,因为整个系统的并发会很大,不是几台机器可以完成的,因此必须用SLB将整个负载分担至 几十台机器上,同时也有两个好处: 1. 可用性大幅提升,单个机器或者某一个可用区(机房)故障不会影响系统 2. 计算的扩展性,访问量大只需要在SLB后增加机器即可。并发量大时接入层很容易成为瓶颈,但是使用SLB的好处是它本身就是一个集群,并且在负载转发上做好了高可用和优化,因此我们只需要简单的配置SLB的端口转发规则即可,其他的基本不需要考虑。
- 应用层,使用python开发,pypy+tornado+Nginx作为后端服务。由于后端逻辑简单,同时为了追求开发速度而选择python,而使用Pypy比原生的CPython速度要提升10倍以上,Tornado的非阻塞异步IO处理方式也可以轻松应对高并发,Nginx作为静态页面的处理也是非常合适的。
- 数据层,由于红包涉及到后续消费时的验证,因此每个红包必须有唯一id。那么生成id和存放数据如果用关系型数据库在压力大时很容易把数据库撑爆,那就要考虑到用缓存来处理,因此最后选用OCS(memcached)作为数据层。而数据的持久化则通过异步处理方式写入关系型数据库RDS(MySQL)(还有一个选择是Redis,具体就不再累述)。
3.雪崩效应和限流解决办法
抢红包、秒杀系统最怕的是雪崩效应,因为访问量的不可预知性。所谓雪崩效应是指单个设备的故障而引起的系统全面瘫痪。 比如本来有20台机器,其中2台坏了理论上是没有关系,但是因为访问量被分配到其他18个机器上,导致这18台的压力突然增加,从而引起更多机器的崩溃,而像雪崩一样,一个地方一个地方沦陷,最终整个系统挂了。 应对雪崩,冗余的资源是必须要考虑的,但是有局限性,因为:
- 不知道该冗余多少。因为访问量是否会超过预期是不知道的;
- 无法做全面的冗余,因为故障有可能在网络,有可能在io,也有可能在数据库,缓存等。因为这些原因只靠冗余是无法保证系统100%的稳定的,那么限流手段就必须要使用了,所谓限流就是当系统访问流量压力超出系统所能承受时应该作何响应,给用户返回排队页面或者让客户稍后重试,这种应答对后台系统基本无压力,同时可以将并发错峰。虽然有点“无赖”,但这是此类系统必不可少的故障应对机制。
在本例中,当后台相应不及时或者压力过大时,会返回给客户一个请稍后再试的提示。
4. 网络架构解读
网络架构层面,阿里云的带宽是BGP的,因此网络质量基本不用担心。并且带宽可以从 1Mbps 至200Mbps随时调整,并且可以通过增加多个SLB的方式来进一步提高整体带宽。同时因为红包页面是静态的,为了进一步提升用户体验,减轻系统压力,使用CDN进行缓存,CDN可以有效降低延迟,减小系统源站压力。
5. 高可用的必要手段
高可用是保证系统稳定和健壮性的必要手段。从整个系统架构来审视高可用,在CDN层面一般都没问题,即便是有问题也会回源,所以这里不用考虑。 SLB的高可用,阿里云SLB本身已经是集群机制提供了容错,同时选了3个SLB也会提高可用性。在虚拟机层面,要避免机器都在同一个可用区(机房),因为一半的机器可放在可用区A,另一半放在可用区B。缓存和数据库层面,阿里云OCS、RDS本身就提供master-slave的高可用机制,因此直接拿来用即可。通过这些我们也能看出来阿里云产品基本都自带有高可用属性,这在我们构建系统架构时节省了大量的成本和精力。
6. 弹性扩展要针对峰值自动调整
为什么我们会强调弹性?因为业务弹性太大,也许远远不及预期的访问,但是也有可能远远超过预期。在网络层,我们选择按量付费,因此峰值就可以自动调整了。应用层的弹性,通过SLB后增加机器实现,同时为了应对突发情况,可以使用ESS来自动扩展,但是本例中未用。OCS也是可以在线升级,只需要点下界面1分钟即可完成升级,而传统服务器如果要扩容,不停机是很难的,并且也没这么快。当然,弹性在秒杀类系统中作为防御性措施,而压力测试就必须做充分。
说到这里,大家可能以为架构已经差不多了,但是还少了两个很重要的:安全和大数据处理。
7. 安全架构很重要
抢购类系统最容易被恶意攻击,无论是渗透还是DDoS攻击,都会对系统和营销活动造成很恶劣的影响。此次活动我们采用阿里云高防IP来应对DDoS、cc攻击,同时http采用https来提升安全性。一些基本的安全扫描也可以通过云盾来完成,还是非常方便的。
8.大数据架构是利器
为什么要考虑大数据?因为在传统IT模式下,基本不会纪录每一个请求的日志,因为这些仅仅用于排错,后续也不会进行分析,日志满了就删掉。传统IT架构数据挖掘的成本太高,产生价值太低,所以大家都把日志丢弃了。那么在本项目中我们把每一个用户的请求都记录下来,传统方式我们会把日志纪录到磁盘中,但是秒杀时每个机器都承担成千上万的并发,反应到IO就是有很多磁盘IO,普通磁盘肯定会拖累系统性能。
因此日志纪录上我们选择SLS,有两个好处:
- 几十台机器的并发日志写入性能没问题;
- 日志统一管理查询,便于后续问题排查和分析;
为进一步的数据分析准备。SLS的数据可以直接转移到 ODPS,因此后端我们用ODPS进行数据分析,我只需要把数据丢进去计算就可以了。
事后也证明保存日志是多么重要,客户也许一开始不需要,但后来想看活动效果,又想要,就可以很方便的完成统计。基本上所有这些因素都是在一个完善的架构中所需要考虑,那么我们的架构设计就基本完成了。
三. 开发测试
1. 整个系统的代码逻辑并不复杂,但是为了应对并发需要全面的考虑;
首先http页面要尽可能小,节省网络带宽,提升并发。当然这种抢购必然要用移动设备,因此移动设备的适配也很重要,H5能够带来很大的便利性。同时页面交互尽可能在本地完成,很多用户会不停的点击,交互要尽可能少的和服务端通信,并且只传输必要信息,比如本项目中的概率数字、唯一id等信息。
2. 性能压力测试;
上线前最重要的就是压力测试,因为预计并发在10万TPS以上,所以我们选用阿里云PTS做压测。PTS的最大好处就是即开即用,需要多少压力源也只需要输入参数即可,不用再去考虑去用Loadrunner之类的软件去搭建压测环境。由于本次抢红包逻辑比较简单,因此压测只需要压测抢红包的url即可。
本例中使用了多个PTS压测集群,最大并发10万。在一开始的测试中发现,单机施压机器大概500左右并发,10万TPS大概需要200台ECS。通过系统参数调优、OCS升级,增加SLB数量至3个,QPS总体提升至10万。压测目的基本达到,而从压测准备到测试完成整个只需要 1天半即完成。传统IT方式一两天时间可能压测环境还没准备好。
压测结果如图(20台机器, 5W TPS)
四、运维护航
1. 7*24 监控
监控是做好系统运维的第一步:一般来说需要监控 服务端口,URL,业务逻辑;
云监控可以提供云资源层面的监控。而应用层、业务逻辑等监控需要使用Zabbix来进行全面的监控。
2. 应急方案
运维方面,最主要就做应急方案了。网络瓶颈如何解决,通过按量付费的方式可以对带宽不做上限限制。快速部署,通过镜像+api的方式,可以瞬间增加几十台机器。
3. 参数调优化
通过调整nginx及linux内核参数,使得单机并发从几百提升至2500;
TCP Conn,tcp_syncookies;
限流通过Nginx参数 limit_req 的burst。
4. 上线及缓存预热
大家都知道CDN在第一次访问时要回源的,第一次之后的访问才会走cdn,秒杀数年会有大量请求瞬间同时到CDN,这个时候CDN还没有缓存,意味着大部分压力都会回到源系统,很有可能直接把系统搞垮。怎么应对,很简单,进行预热。 预热也很简单,用阿里测或者17ce等在线测试平台多测几次,这样全国各地的CDN几点都进行了缓存,当业务开启正式客户进来时直接就可以从cdn返回。
5. 自动化部署
在系统运行或项目过程中,难免会遇到需求变更需要去修改代码并部署的,使用ansible来对几十台及其进行快速部署。
最终整个系统的架构如下:
老庙黄金2016春晚抢红包活动技术架构
具体来解读下:
- 网络层:DDoS防护、域名解析、CDN加速;
- 接入层:主要是4层负载均衡SLB,将访问请求分发至后端服务器;
- 应用层:将虚拟机ECS分为两个可用区A和B来提高系统整体可用性。OCS用于做数据缓存,MQS则通过消息队列方式将一些数据异步写入数据库。而所有服务器的日志都集中记录入SLS,为后续的数据分析做好准备,同时也方便日志的查找;
- 数据层:由于单个RDS的性能有限,因此使用DRDS来组成一个RDS MySQL集群,将系统压力分担至多个RDS;
- ODPS则用来做最终的数据分析,比如用户量、访问量、用户行为等;
- 运维监控:云监控和Zabbix结合来实现整个系统从云资源到应用到业务的监控。Ansible用于自动化部署;
最后再强调一下,整个系统从需求调研到开发,再到压力测试和上线只用了2周时间,在春晚活动中,整个系统表现非常稳定,很顺利的扛过了峰值压力。而在成本方面,这样一个系统使用传统IT方式软硬件投入100万是至少的,而云的按需付费模式在此项目中成本只需要1/10还不到。这种时间紧、任务急、很复杂的项目在传统IT模式下几乎是mission impossible,这也正是云计算所带给我们的力量。