你好,欢迎来到第 03 讲,这一讲主要介绍秒杀系统的非功能需求分析,特别是涉及高可用、高性能、高并发方面的内容。
前两讲,我们介绍了秒杀系统的前、后端功能需求,许多人在做业务系统时会发现,虽然功能自测、QA 测试、线上测试都通过了,但当线上环境出现变化(比如大量用户瞬间涌入),就会出现诸如系统瘫痪、数据错乱等问题,导致交易失败。
那如何预防此类问题,设计出稳定可靠的秒杀系统呢?这就需要我们这一讲介绍的非功能需求了。
什么是非功能需求?我们先来回顾下需求分析的过程,当你接到一个项目后,除了分析功能需求外,还应该思考些什么?
也许,你会想到:
这个系统的用户是谁?
有多少用户?
用户都在什么时间使用系统?
用户可能会做哪些危害系统的 *** 作?
假如你能想到这些,说明你已经开始从系统功能以外来思考需求了。但仅仅解决这些问题,我们的系统就能正常运行吗?事情没那么简单。
除了外部,我们还需要更多地从内部因素考量,比如运行系统的机器配置、语言并发能力、机房可用性等等这些是否满足要求。像这种除用户使用功能之外的潜在需求,就是非功能需求。
具体来说,非功能需求包括:可用性、并发能力、性能、安全防护能力、水平扩容缩容能力、运维/运营成本等。
比如,我们在设计一个重要系统时,可能会要求可用性达到 99.99%,并发能力达到 100 万 QPS,请求延迟低于 500ms,能防范跨站脚本攻击,1 分钟内快速扩容,总成本控制在 10 万元每月。这些要求就是非功能需求要满足的。
为什么要关注这些指标? 因为如果没有满足这些指标,系统在运行的时候,会出现重大故障。甚至可以说,满足它们是系统在特定条件下正常运行的最低要求。
举个典型的例子:
某个金融系统要求每年最多只能发生一次故障,故障时间不能超过 10 分钟,为此他们还准备了故障赔偿金。但是在项目部署的时候,相关人员因为没有充分评估机房的网络质量,结果在两次流量高峰时都出现了故障,不仅影响用户体验,还导致赔偿金严重超支。
那么,为了在系统设计上防范此类重大故障,保证系统正常运行,我们该怎样分析非功能需求呢?
如何分析非功能需求?首先,请你思考几个与非功能需求有关的问题:
假如总共有 100万用户,在同一时刻访问我们的系统,那么系统能否扛住?
假如 10 台服务器中有一台服务器因为物理故障瘫痪,剩下的服务器能否扛住?
假如服务器所在的某个机房发生了火灾,系统该如何继续运行?
假如有人在恶意攻击,系统该如何稳定运行?
假如请求超过 1 秒用户就会失去耐心,如何保障请求延迟低于 1 秒?
假如系统容量不足,如何做到 30 秒内快速扩容缩容?
这一系列的“灵魂拷问”,就是分析非功能需求的常用方法:假设在某些极端条件下,系统能否稳定运行,会面临哪些风险。这些极端条件我们怎么去找,怎么去假设呢?
我们可以根据影响系统正常运行的各种因素来假设。为了便于分析,我们将这些影响要素分为与系统运行环境有关的内部因素,以及与系统运行环境无关的外部因素。
那么,影响系统正常运行的内部因素主要有哪些呢?具体有这几个方面:
系统使用的语言和基础组件,比如采用 Golang 就意味着得到比用 PHP 更好的并发性能;
系统运行的服务器环境,比如采用多核 CPU 必然能提供比单核更好的性能;
服务器所在的机房环境,比如选择双电双网的机房将意味着比单电单网的机房更高的可用性;
机房所在的地理环境,比如选择无地震、洪水、台风的地区做容灾备份风险,将比在地震带低很多。
以上是内部因素,接下来咱们看外部因素,它主要有:
系统面向的用户群,比如一线城市年轻人、三四线城市用户;
用户群体数量有多大,比如 100 万用户量、2 亿用户量;
用户集中访问时间段,比如上班族是集中在下班后刷抖音,还是夜间 11 点刷;
用户可能会做哪些 *** 作,比如疯狂点击按钮或者恶意攻击。
那么,这些因素在什么情况下可能给我们的系统带来风险?又该如何防控这些风险呢?
前面提到,非功能需求是系统在特定条件下正常运行的最低要求。所以,在系统的设计之初,我们就应当给这些最低要求赋予明确的定义,给出明确的指标。
对于秒杀系统来说,它的核心非功能需求主要有:高可用指标、高性能指标、高并发指标,比如可用性方面要高于 99.99%,高性能方面要求请求延迟小于 100ms,高并发方面要求QPS 大于 10万。这三个指标俗称“三高”要求,公司不同,指标大小要求也会有所不同。
那,哪些内外部因素会影响秒杀系统的这三高要求呢?如何通过各种因素来计算最终的指标? 接下来我们依次分析下。
如何计算高可用指标?高可用指标是指用来衡量一个系统可用性有多高。这里有几个需要了解的概念:
MTBF(Mean Time Between Failure,平均可用时长),系统正常、稳定运行的平均时长,比如三天内系统出现了3次故障,每次持续1小时,那么平均可用时长是23小时;
MTTR(Mean Time To Repair,平均修复时长),系统从失效后到恢复正常所耗费的平均时间,比如前面提到的每次故障持续1小时;
SLA(Service-Level Agreement,服务等级协议),用于评估服务可用性等级,计算公式是MTBF/(MTBF+MTTR),一般我们所说的可用性高于 99.99%,是指 SLA 高于 99.99%。
通常我们在看监控数据的时候会关心这个指标。在使用第三方服务和平台的时候也会关注第三方平台的可用性指标,如某第三方支付平台可用性高于 99.999%。
那么,在实际项目中SLA应该如何计算呢?SLA的计算规则如下。
如果一个系统的正常运行还依赖多个子系统,如下图所示,系统中有 a、b、c、d 四个子系统,只要其中一个子系统不正常,整个系统就无法正常工作,那么整个系统的 SLA = SLA(a)*SLA(b)*SLA(c)*SLA(d)。
假如四个子系统的SLA分别为 99.99%、99.995%、99.995%、99.999%,那么最终的 SLA 为 99.979%,整体SLA小于每一个子系统的SLA。
多个子系统图
如果两个子系统作为主备关系提供服务时,只有两个子系统都出问题了才会影响整个系统,那么SLA=1-(1-SLA(a1))*(1-SLA(a2))。如下图所示,如果 a1 系统的 SLA 为 99.99%,a2 系统的 SLA 为 99.995%,那么系统最终的 SLA 为 99.9999995%。当然这是理想情况,主备切换也是需要耗费时间的,实际计算的时候需要将主备切换耗时考虑在内。
系统主备示意图
那么,影响SLA的因素都有哪些呢?以下列举一些可供参考:
服务自身因Bug挂掉或无法正常工作;
服务因机器物理故障导致无法正常工作,比如磁盘坏块、内存颗粒坏了、主板故障等;
服务器物理机因机房断网、断电、空调损坏无法降温等原因导致机房故障;
地震、洪水、台风等灾害导致机房损坏;
服务依赖的组件故障导致无法正常工作;
被黑客攻击导致无法正常工作;
并发量超过系统承载能力,导致系统崩溃、数据错乱。
以上各种原因都可能影响 SLA,只是概率不同而已。有的概率很低,对总的 SLA 影响较小。不过,有一个基本原则:下层系统的 SLA 在设计上通常需要高于上层系统的 SLA,只有下层系统的 SLA 足够高,上层系统的 SLA 才更容易得到保障。后面我们会有几节课专门介绍下层系统如何保障 SLA。
如何计算高并发指标?通常我们用 QPS(Queries Per Second,每秒查询率)来衡量系统承载能力。
不同业务的系统,对并发的要求可能不一样,比如 ToC 业务用户量大,对并发要求高,ToB业务系统可能用户量小,对并发要求相对较低。
即使同样是 ToC 业务系统,不同功能对并发的要求也可能不一样,比如抢购和秒杀对并发的要求会比下单的并发要求高。如何准确地评估高并发指标,这需要我们从用户增长、用户习惯、业务形态、系统承载能力等方面进行分析。
对于秒杀系统来说,通常用户数都是远大于库存数的。库存一旦抢完,秒杀活动基本结束。我们可以针对秒杀活动的特点,做以下分析。
用户增长:月/年用户增长量是多少?是否有在社交平台推广?
用户习惯:秒杀活动期间是否跟用户活跃时间重叠?用户是否会频繁点击秒杀按钮或者刷新活动页面?
业务形态:是否是爆品?商品在购物车超时时间是多少?下单超时时间是多少?超时后库存是否需要归还?
系统承载能力:系统底层数据库等资源承载能力如何?业务系统是否要扩容?
总的来说,并发指标需要综合评估,还需要权衡成本和收益,毕竟大多时候并发能力需要靠堆机器来提升。
举个例子:
某电商通过观察数据统计得知,自己的日活大概有 600 万。活动期间,运营团队在社交媒体上推广,预计可拉新 50 万,那么活动当天日活大概就有 650 万。根据经验,活动期间活跃用户占日活用户 70%,那么参加这场活动的活跃用户大概有 455 万。
假如有一爆款商品,库存只有 1000 件,预计会有 30% 的活跃用户参加秒杀,那么参与抢购的人大概是 136.5万人。假如每个用户每秒触发 2 次请求,那么业务服务承载的 QPS 最高可能达到 273 万。另外,我们还知道它的底层 Redis 承载能力为 1 万 QPS。
根据业务服务承载最高值达 270 万 QPS 以及底层 Redis 承载能力 1 万 QPS,我们预留 10% ~ 20% 的余量,可以初步制定出并发指标:业务服务300万QPS,底层资源 8000QPS。
这里你可能会问了:为何业务服务的 QPS 要比实际的高,而底层资源 QPS 却比实际承载能力低呢?
其实这是一种保护措施:业务系统设计上保留余量,要比计算出来的 QPS 高一些,以防实际突发流量高于估算值导致系统不稳定;底层资源一般比较固定,不容易扩容,需要限制QPS不能超过其承载能力。总的来说,系统资源在设计上要留有 10% ~ 20% 的余量,以便应对突发流量。
得到上面的数据后,我们还要通过压测来评估业务服务目前的容量是否达到要求,是否要扩容。
如何计算高性能指标?在非功能需求中,除了可用性外,性能也是影响用户体验的因素之一。对于 ToC 的业务来说,如果请求超过 2 秒返回,会影响用户体验;如果在 5 秒内没有响应,用户可能就会离开。
那性能指标受哪些因素的影响呢?它的影响因素主要有:
用户网络环境
请求/返回数据大小
业务系统 CPU、内存、磁盘等性能
下游资源性能
算法实现是否高效
请求链路长短
怎么计算呢?举个例子,假设某秒杀系统的用户网络环境延迟 100ms,请求/返回数据处理为 10ms,业务服务内 *** 作磁盘 30ms,业务服务请求下游资源 10ms,算法计算 5ms。我们把这些环节的延迟加起来,总共耗时将超过 155ms。
这个数值有什么意义?它说明,从用户发起请求到用户收到服务端返回的结果将超过 155ms。如果超过 150ms 会流失 10% 的用户,这可能是业务方不希望看到的,这个时候我们需要继续优化性能。
当然,不同并发压力下,请求延迟可能不同。通常来说,并发压力越大,平均请求延迟也越大。这好比排队买东西,排队的人越多,最后一个人买东西耗时越长。所以,我们在评估性能的时候,通常需要跟并发指标关联起来。例如,并发低于100万时,平均请求延迟不高于200ms。
通常,在实现完代码后,不一定确保性能满足要求,需要我们做大量的性能测试和性能调优来满足性能要求。后面我们会有专门的课时来介绍如何做性能测试和性能调优。
小结这一讲我们分享了非功能需求的意义,它是除功能需求以外的、保障系统稳定运行的最低要求。对于秒杀系统来说,非功能需求主要有可用性指标、性能指标、并发指标。
如何分析非功能需求呢?分析的时候,我们需要充分结合业务特点和资源环境来综合评估。根据业务特点分析外部因素,根据资源环境来分析内部因素,综合评估出合理的指标,切忌盲目定指标。还有,并不是指标越高越好,满足过高的指标可能会浪费很多不必要的资源。
计算“三高”指标的时候需要非常清楚计算指标需要的各种参数,比如活跃用户量是多少、库存多少、网络质量怎样等。另外还要结合多个系统间的依赖关系,判定采用哪种计算方法,是并行关系还是串行关系。这样才能计算出较合理的指标,即满足业务要求,又不会投入太多额外资源。
思考题:一个日活 1 亿的公交支付 App,80% 用户活跃时间在 08:00 ~ 09:00 和 20:00 ~ 21:00,该如何给它定“三高”指标?
你可以把自己的想法写到下面留言区哦。
这一讲就介绍到这里了,下一节我们将介绍“如何设计秒杀的系统架构”。
《Java 工程师高薪训练营》
实战训练+面试模拟+大厂内推,想要提升技术能力,进大厂拿高薪,点击链接,提升自己!
精选评论 **0267:
讲师回复:公交app计算三高,老师给我们参考解释吧,多谢多谢
*明:计算三高要参考具体业务背景,假如在北京这样的大城市业务背景是这样:全市每天运营 2 万辆公交车,高峰时间支付 QPS 为 1000,全天有 1000 万次请求。如果高峰时间故障了,哪怕是 1 秒,全天的 SLA 也会不到 99.99%。如果要求 SLA 达到 99.999%,那么可以在刷二维码的机器缓存请求异步提交。高峰时期 QPS 受各种因素影响较大,比如堵车,并发能力需要有足够余量,比如 2000 QPS。平均每个用户支付完成时间 2 秒,也就是请求延迟低于 2 秒。
**良:高可用:系统故障时快速恢复。例:人工:5分钟内恢复。 自动化:30s内恢复。高性能指标:sla达到5个9,每次请求超过2s算失败。高并发:支撑5万qps
讲师回复:大佬 之前用jmeter进行压测 单机的最多1000个线程 压测服务器就撑不了,压测过2w tps的情况 用了 20台压测机 这百万并发10台jmeter够吗?或者其他的压测工具吗
**风:jmeter可能不够。这种高并发压测我通常是用自己写的工具,为了节省压测成本。毕竟服务器也是要花钱的。课程中有介绍高并发压测工具的实现。
讲师回复:一台12核的机器同时最多可以运行12个线程,跑12个请求,百万并发是怎么弄出来的呀
**风:不能简单认为 12 个线程就只能跑 12 个请求,并发不是并行。一台12核32g的机器能模拟的并发还跟网络性能有关,跟能使用的端口数量有关。使用容器增加可用端口数,压测前将最大文件数量设置为 100 万。我本地笔记本电脑压测用了 3 核并发达到 2.5 万 QPS 以上,12 核的话至少能达到 10 万 QPS。100 万并发的话,至少要 10 台压测机器。
讲师回复:老师,请问下,你们使用压测的时候百万并发是用集群去测得吗?一台12核32g的机器,大约可以模拟多大的并发?
**升:大流量系统压测,如果是全量压测,必须要用集群去压。但即使用集群去压,如果机器数量和性能不够,无法压到实际的并发能力。因此,通常是用集群去压单节点,集群性能通常跟单节点性能和节点数相关,压单个节点也能基本评估出集群的整体并发能力。
讲师回复:高可用: 5-10分钟重启,sla不知道咋个算,高并发为2万qps,高峰段4000万分为早上和晚上,则单个高峰段每秒12000次,预留10%-20%则为2万。并且由于公交app并不是实时要求非常高,因为可以延迟提交乘车信息。
由于是涉及支付功能的应用,而且公交刷二维码支付要求快速响应,试想一下早晚高峰期间很多人排队上车,如果支付的时候出现故障会影响很多人。所以后端 SLA 要求达到 99.999%。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)