《英雄联盟》S11全球总决赛·决赛中国战队夺冠,赛事直播盛况空前,观赛人数破亿。B站作为英雄联盟2021全球总决赛直播独家版权方不仅在整个比赛过程中保证了直播整体总体运行的平稳,还抗住了超预期的流量。
如此大型的直播活动,B站究竟是如何保障系统稳定的呢?
以下内容整理自TakinTalks·live直播活动中B站吕帆老师的精彩分享。
吕帆
哔哩哔哩直播B&C端架构组leader
个人简介: 毕业于华中科技大学,硕士。曾就职于美团点评,蚂蚁金服等公司,拥有丰富的服务端研发开发架构经验,对于高可用高并发系统设计,系统稳定性保障,服务治理,单元化部署,网络协议,加解密,互联网常见业务(直播,营销,开发平台,交易等)等方面较多实践经验。
为了保障这场活动的稳定性,B站投入了近4个月的时间,上百人参与其中,从7月份就开始了相关筹备工作。总体规划包含Web端、移动端、服务端、运维、直播流、采购等多类型事务,同时涵盖了公司8个以上的团队、10余项大项执行项目。为了给到用户最佳的视听互动体验,反复打磨每一个使用场景、进行多轮压测、混沌测试、预设降级策略、限流策略、设定预案/SOP、临场保障等,从而保证该赛事直播的顺利进行。接下来我将从这里面挑一些重点来跟大家分享。
前置优化有3块主要内容:服务规范化、制定指南针指标、日志的梳理与告警。
一共梳理了16条规范,其中有7条是需要大家重点关注的,可以简单分享一下其中几点内容。
服务之间的调用,服务调用存储层(Mysql、Redis)需要设置合理的超时,这个点没有经历过高并发高可用场景的话可能会不太理解。我们之前经历过这样一个事件,当时有个服务调用数据库,我们的超时设计不合理过长了,结果因为数据库抖动,我们整个服务都卡着等超时最后整个就挂掉了。这就是为什么我们会单独列这条规范了。
调用外部服务或者存储层如果重试的必要,需要有限的合理的重试,这也是从我们之前的经历中总结出来的规范。之前有个开发同学特别有心,想着Redis大部分是读比较多,为了让借口的性能提高,他做了一个重试,重试次数设置了5次。其实想法是好的,但遇到极端情况就出现问题了,当时这个Redis集群有一个节点抖动了于是产生了大量的重试,这个节点的流量一下增加了5倍,结果就打挂了。
指南针指标是服务对业务的核心价值体现,指南针指标同时也体现服务的健康与否 ,指南针指标的波动,一定意味着业务出现波动,业务出现问题,指南针指标一定异常。所以只要制定了正确的指南针指标,并加以监控和告警就能及时反馈系统问题。
出现问题大家的第一反应基本都是去看日志/监控,但就如同下图,有写告警它并没有告诉你影响这么样、发生了什么事情,那这就是无效的告警,无法帮助开发进行定位为题治标不治本。
为了让日志和告警发挥它原本的作用,我们对日志进行了分级并提出了规范要求,必须要体现报错的原因以及具体的解决方案。同时我们喧杂在可能出现故障的地方打日志设置告警,这样就能快速准确定位问题和解决了。
文末附课件下载方式
对于多数研发来说,关注的仅是自身服务是否可用,但是由服务串联成的场景才是实际用户感知的使用过程。定义场景能帮助我们更好的识别场景、理解场景、利于保障,是保障的基础。我们将场景的定义罗列了5项,其中场景级别、场景交互(包含上下游)、相关接口是比较重要的梳理项。
以B站的直播首页为例,大家可以看看我们针对一个具体的场景会梳理哪些内容。基于这一套梳理流程,我们一共梳理了40+的实际场景。
系统的压力来自于海量用户每一个行为的流量。梳理好场景后,我们需要从入口梳理出每个场景的流量,也就是这个场景需要承受的QPS,然后再具体到这个场景涉及的每个接口的QPS,如进入直播房间场景:
从上图,我们总结出进房场景涉及的服务和接口以及对应的QPS。这里有必要说一下QPS的预估方法,主要有两种:
此算法比较适用于一些老的场景,老的接口。
(GMV\DAU\订单量)为输入,根据日常业务量-流量转化模型(比如经典漏斗模型)换算得到对应子域业务体量评估。
此算法比较适用于一些新的场景,新的接口,特别是本次活动新增的。
保障系统稳定性最大的难题在于容量规划,而容量规划最大的难题在于准确评估系统的实际承载能力。通过压测可以评估系统的实际承载能力。另外,高并发时,压测可以检测到一些在流量比较低的时候发现不了的问题。这次我们共进行了三轮压测,每轮压测都会执行多次:
第一轮:先不扩容,压出系统的极限,找出瓶颈和优化点
第二轮:等系统优化和业务需求做完,扩容后,按照S11预计流量压测
第三轮:验证,回归,查漏补缺
这里有总结一些压测的常见问题以及背后的原因,仅供参考。
文末附课件下载方式
经过多轮的压测,我们也总结出了压测时应该注意的事项:
虽然压测已经做过,但这只是在系统正常运行情况下的表现。真实情况中,线上系统经常会出现各式各样的异常,那么我们能否主动找出系统中的脆弱环节,提前做加固、防范呢?另外保障的核心还是在于人,所以我们还需要锻炼参与保障的同学,让他们能够临危不乱,冷静的解决遇到的问题,为此我们引入了混沌工程。 本次混沌实验的目的:通过故障注入,验收证明全链路的高可用性, 包括监控、告警、定位、恢复体系。主要聚焦在以下几个最常见的故障场景去做演练:
以下为本次我们的推进过程:
根据部署架构图,可以清楚地看到服务所依赖的各种资源的关系,这样就可以根据部署架构图在每一个调用链路上设置故障点。
根据部署架构图,可以设置DB不可用/不稳定,Cache集群不可用/不稳定,依赖的RPC服务不可用/不稳定,机器宕机,网络抖动等故障
演练由测试同学在任意时间触发任意故障,然后记录开发同学可否1分钟发现故障,五分钟定位故障,十分钟解决故障。同时记录故障演练的过程,参考如下:
文末附课件下载方式
根据以往经验,故障演练可以分至少两轮,第一轮对所有故障点进行一场演练,演练完之后进行系统优化,第二轮可以采取”考试“模式对故障点进行抽检。
前面介绍的都是如何保障系统不要出现问题,那万一真的出现问题了该怎么办呢?总结一下线上问题的处理手段一共有5种:限流、降级、熔断、扩容和Hotfix(改代码上线)。
要想在大型活动的高并发流量场景下,快速对线上紧急事故进行响应处理,仅仅依赖值班同学临场发挥是远远不够的。争分夺秒的情况下,无法给处理人员留有充足的策略思考空间,而错误的处理决策,往往会导致更为失控、严重的业务与系统影响。因此,要想在现场快速而正确地响应问题,值班同学需要做的是选择题,而不是陈述题。而选项的构成,便是我们的预案。保障S11顺利播出,我们对每个场景整理了一套处理问题的“标准作业程序”,也就是所谓的SOP。每一个SOP大致有下面四点:
降级目的是削弱非核心服务资源占用,保证业务核心服务稳定性。降级策略有很多方面需要思考与落地,在这里总结一下经常用到降级策略。
降级的实现方式,大体分为两种,一种是自动降级,一种是主动降级。
了解了降级方法之后,我们还需要清楚不是所有服务都能降级,也不是等到故障发生了以后,才去选择或者确定哪些服务可以降级。故障的降级策略一定要提前规划与思考。 系统或者服务需要分为核心和非核心。核心服务是我们力保不能有任何问题的主流程服务 P0;非核心服务,又可以根据重要性进行再次分层。可以划分为 P1、P2、P3 服务:
在梳理服务等级的时候,需要注意 2-8 原则,也就是 20% 为核心系统,80% 为非核心系统。因此我们主要精力要放在20% 的核心系统。在本次S11稳定性保障中,我们做了一定的降级策略如:
大型微服务架构中的任何服务节点,不管怎么优化,怎么拓展,都会有能力上限。如果达到能力上限,系统服务崩溃的可能性就会增加,这种情况也很容易造成整个微服务应用的雪崩效应。 当服务器的压力剧增的情况下,为了保证服务不被拖垮,对一些流量采取拒绝或者降级的策略,以此来保证核心服务的正常运转。这是一种有损的技术手段。 因为限流是一种有损的技术手段,而且平时使用的情况不多,所以如何决策是否要做出限流操作,在S11的活动中我们做了如下定义: 大前提:流量的突然增加,或者依赖的资源(比如存储层)有异常(可能是流量突增导致也有可能是存储抖动导致)且对业务有损,短时间没有有效的恢复手段,系统无法承受当前流量,且认为限流可以缓解当前情况 举个例子:
限流不是目的,只是解决当前紧急情况的一个手段,并且对系统是有损的,所以要持续关注限流的效果和对系统的影响,并且及时解除。 本次S11,我们分别对核心接口做了:
临场保障主要涉及值班人员安排和现场保障与事故记录两个方面,这边就不展开了。
今年B站还会有S12赛季直播活动,所以我们现在也是陆陆续续开始相关的保障工作了。与之前相比,今年新增了多机房部署,这个也比较常见,就是某个机房出现问题了就可以快速把流量切换到另一个机房。B站的直播主要是读流量,所以我们做的是读流量的多机房部署,整体还是比较容易的。此外我们还在探索单元化和多活方向的保障手段,到时候可以再跟大家分享分享这部分的内容。
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞0
添加新评论0 条评论