当前位置: 首页 > 科技观察

持续保证系统的稳定性和高可用:混沌工程在腾讯游戏中的实践_0

时间:2023-03-21 11:36:08 科技观察

最近一两年,我们可以发现混沌工程的技术非常火爆,大家都知道它成为了一个新的风口.人们常说做事要顺势而为,我们希望抓住这个机会,所以我过去一年的工作主要是在腾讯游戏中实现混沌工程的技术。一、什么是混沌工程1、混沌工程的定义混沌工程是为处理故障而诞生的。大家都知道我们的运维人员很辛苦,经常周末或者半夜起来处理各种故障。为了减少这种现象,更有效地处理故障,混沌工程应运而生。混沌工程通过主动注入故障提前暴露系统问题,发现系统中可能存在的一些风险点,进而提前解决这些问题。即使我们的系统在半夜或周末出现故障,我们也可以高枕无忧。上图中的内容是Netflix的书中对混沌工程的定义。简单来说,就是通过主动注入故障,提前发现问题,进而解决问题,规避风险。2、混沌工程的作用混沌工程的出现就是为了有效地处理故障,其作用可以分为以下六点。1)故障预防混沌工程的核心点是预防故障,通过主动注入故障提前解决故障。2)故障发现混沌工程可以帮助我们提前发现故障。例如,我们使用混沌工程来检测我们的报警监控系统和舆情,并定期检查这些系统是否有效。通过注入故障验证系统的有效性,我们可以提高故障检测速度并缩短平均故障检测时间。3)故障响应做混沌工程也可以加快我们的故障响应。比如我们下班后可能经常会做混沌工程,看看我们团队的反应速度有多快,组织协调上是不是出现了一些问题。这样可以提高我们整个团队的战斗力和故障响应速度。4)故障定位混沌工程也可以帮助我们定位故障。通过混沌工程,判断是否能及时发现故障;我们系统的一些检测工具、Matrics、Log、Trace等可观察平台是否可靠;我们的诊断工具能否及时定位到根本原因。这样可以加快我们的故障定位,提高效率。5)故障恢复发现故障后,我们需要对故障进行修复。通过混沌工程,我们还可以测试故障转移、限流熔断、降级等策略是否有效,应急预案能否快速修复,缩短我们故障的平均修复时间。这也是我们做混沌工程的重要起点。6)检讨与改进故障结束后,我们往往要对故障进行检讨。故障修复后,我们在生产过程中很难重现。通过混沌工程,我们可以方便高效的回顾自己项目中出现的一些失败,这也是混沌工程的一个重要作用。综上所述,混沌工程可以通过提前主动注入故障、发现问题、解决问题来降低我们生产环境出现故障的概率。2.混沌工程平台建设谈到混沌工程的实践,业界有一套方法论。通过理解和总结,我分为5个环节。搞混沌工程,首先要有平台。该平台可以制作故障,实现故障编排,同步观察实验结果,输出实验报告。完成实验后,发现问题、跟进问题、解决问题,解决问题后再次提交验证。通过这个闭环,不断提升业务的稳定性和可靠性是混沌工程的核心理念。在腾讯游戏的具体实现中,我们通过混沌实验的全生命周期设计了这个平台。1、流程设计1)做实验前先要有故障的创建和注入能力,要有故障场景。这里的故障场景是指故障原子。我们希望实验平台能够提供丰富的故障原子,可以组合起来模拟网络中可能出现的各种故障。在实验过程中,实验平台必须能够对接我们现有的系统或者公司现有的一些监控系统,比如一些基础监控,或者业务特性的指标监控,并集成到实验平台中。我们的混沌实验平台还需要管理我们的实验目标。比如我们的一个K8S集群,一批IP,或者一个物理集群等等,要能够对目标进行分类,管理通常所说的爆炸半径。接下来,我们需要能够编排实验,通过一些拖放的方式编排一个混沌实验。这是这个平台在实验之前应该具备的能力。2)在实验中在实验中,我们的核心点是希望平台能够在注入故障的同时观察实验的效果,即边做实验边看效果。实验过程中可能会出现一些意想不到的异常情况。我们必须有一个在极端情况下自动停止实验的策略。实现良好的实验保护也是我们平台需要具备的能力之一。我们还希望该平台能够应对故障。实验完成后,可及时恢复现场环境。3)实验结束实验结束后,平台需要输出实验报告。实验中发现的问题需要通过实验报告来呈现。我们需要对实验报告进行总结分析,看看是否发现了新问题、新隐患或新知识。我们需要对得到的结果进行分析,对发现的问题进行跟进,并实施解决问题。我们也做了很多统计分析。例如,游戏的质量分数是多少?近日,英雄联盟手游上线。通过统计分析,它的得分很高,稳定性和可靠性也很好。2、故障原子混沌实验平台的核心能力是故障注入,人为制造各种故障和破坏。腾讯游戏主要使用自主研发的混沌工程引擎,以及其他一些行业开源引擎。我们引用ChaosMesh等引擎来整合我们的实验。有了这些底层引擎,我们得到了很多故障原子。存储层面:Io高负载、Io延迟、Io错误、文件句柄耗尽等故障原子。计算资源级别:CPU负载高、负载满等故障原子。网络层面:延迟、丢包、乱序、重复、满带宽、端口耗尽等故障原子。在节点/容器级别:关闭一分钟,删除Pod,杀死容器,杀死Pod和其他故障原子。应用层:故障原子,如进程死机、进程崩溃、HTTP协议状态码错误等。定制化:可制定机器脚本,如编写shell脚本、Python脚本、go二进制包等。通过上传这个包,我们可以在其中注入故障,从而可以针对一些特殊的业务场景进行定制化开发。基本上有了这些故障,我们就可以在生产环境或者实验环境中通过随机组合来模拟各种网络故障。3.应用故障注入推荐ChaosMesh产品,专门针对K8S场景设计,可以模拟pod、network、io、kernel等各个层面的故障。我们使用ChaosMesh产品已经一年多了,效果很好。通过这个工具,我们可以直接在K8S环境中进行故障注入,成本更低。在实验过程中,我们发现即使是在计算资源、网络等基础层面的故障原子,也不能完全满足要求。我们有时不得不在服务上做一些应用程序级的故障原子。由于腾讯游戏的大部分服务使用的是HTTPS协议,所以有时可能需要对服务的某条路径、某部分用户、某区域的玩家进行故障实验。这时候就需要通过网关MESH这个过程来做这个实验了。在我们的服务架构中,每一个服务前面都有一个网关,所有的流量都会通过网关流向真正的后端服务。通过统一平台实现对网关的分配或遥测。所有流量都会经过网关,因此网关可以管理流量。许多公司应该使用这种架构来管理流量。我们可以限流、降级、熔断流量。另外我们还可以对流量做一些劫持和二次处理,这就是混沌工程可以做的事情。具体来说,当流量从网关进来后,我们可以修改它的状态码。比如原来的状态码是200,我们改成4xx;或者我们可以注入延迟并在休眠一段时间后返回服务;而且,我们还可以注入一些header,修改stripping等,甚至可以对带宽进行修改。限制和过滤用户。这样,混沌工程就可以在应用层给玩家注入故障。使用传统引擎在应用层面的故障注入成本非常高,但是有了网关MESH能力,故障注入的成本会非常低。比如我们要对某个玩家或者某个群体的玩家做故障注入,那么配置就很简单了。我们只需要在平台上选择我们的实验对象,配置规则并提交,实验即刻生效。这个时候我们就可以在客户端体验故障注入是否有效,对玩家有什么影响。这样,失败只影响这群玩家,对现网其他玩家没有影响。我们的爆炸半径可以控制的很好,失效的范围和失效的风险也可以在一定程度上得到控制。这也是网关MESH能做的。带来的好处。4.实验安排毫无疑问,故障注入是混沌工程的核心能力,但混沌实验平台除了故障注入,还应该具备边做实验边观察效果的能力。平台需要能够协调。现网的实验可能非常复杂,只有通过各种实验场景以及我们的实验目的、对象、实验对象的结合,才能复现或模拟故障。我们需要一个地方来集成和控制实验配置。比如上图中,我们想把CPU烧到80%10分钟,就可以通过这个表单提交。我们要延迟1秒10分钟,也可以通过这个表格提交。这样我们的实验目标,实验配置,我们要观察的稳态指标(实验过程中我们要同时观察的指标)都可以通过编排串联起来。编排能力可以极大的提高我们实验的效率,这个能力也是混沌工程实验平台必备的能力。5、有了实验观察的安排,我们也希望在实际做实验的时候同步观察实验的效果。实验效果可能是一些基础监控平台的指标,比如一些最基础的IaaS层的监控;也可能是QPS、时延、同时在线人数等一些业务特性指标,这些都是混沌平台没有的。在腾讯游戏中,我们对业务的基础监控和一些特色监控进行打通、打通、整合。这些现有指标可以直接集成。如果没有指标,我们也提供通用指标。用户可以直接在平台上暴露指标并进行配置。收集规则,让我们主动拉取用户的业务指标,这样在平台进行实验的时候,可以同时观察这个实验对用户服务的影响。这种方法实现了整个指标的透明化,这是实验观察得到的好处。6.实验报告做混沌工程其实有点类似于去医院体检。去医院体检后,医院一般会输出一份记录身体各项指标的报告。这些身体指标是否超过健康阈值,都会在报告中标明。当医生发现参考值过高时,会提醒我们多注意相关方面,并提供一些建议,在下次体检时注意这些指标是否有所改善。在做体检的时候,我们最想要的就是这份报告,它能够体现出我们体检的好处。混沌工程也是如此。我们进行了混沌工程实验。有没有好处,有没有发现问题,都应该在报告中体现出来。我们希望这个平台能够永久持续地存储整个实验过程中的一些历史数据、编排数据、稳态指标等数据,方便我们以后随时追溯我们实验的过程数据。我们有了数据之后,希望能够分析数据,发现问题。发现问题是混沌工程的目标。发现问题后,我们希望能够对问题进行分类,将问题分配给具体的责任人,让他跟进解决。这样,我们的实验就会达到一个很好的闭环,这就是上面提到的核心概念。不断发现问题,解决问题,形成循环是我们实验的初衷。七、好处做了这么多,有故障原子,有实验安排,有实验报告,有什么好处?大家知道,在混沌工程提出之前,我们也会进行一些容灾演练。看来不用混沌平台也可以做到。经过实验,我们总结出来的好处如上图所示。在没有乱七八糟的平台的时候,我们做实验的时候,要自己写脚本,自己写工具,自己开发工具,自己测试,自己编排。一个复杂的场景,可能要我??们自己串联起来。还是要执行,观察效果。效果数据可能分散在各个平台。我们可能要不断地在各个平台之间切换,才能看到实验的效果数据。一次故障向下钻取至少一个小时或更长时间。有了混沌实验平台,我们的实验效率得到了极大的提升。我们安排一个实验,它的目标,实验配置,观察指标,几乎可以做到分钟级。几分钟的时间,我们就可以安排好整个实验,然后一边做实验一边观察效果,??同时发现和分析问题,大大缩短了实验时间。综上所述,降本增效是混沌平台的好处。3.混沌工程实践有了平台,你不一定会用,我们要实践。练习的目标非常明确。提高我们的基础设施、平台、业务和应用的可用性和稳定性,检验组织协作的效率,检验组织的协作方式和流程是否合理。我们有以下实践要点:控制风险。自动化实验。我们的很多业务版本迭代非常快。如果我们每发布一个版本都要跟进做实验,会产生非常高的人工成本,所以我们需要做一些自动化的实验。红蓝对峙。提高组织团队的协作能力。1.风险控制做混沌工程会对业务和系统造成破坏。我们混沌工程的目的是通过主动输出故障来发现问题和解决问题,所以风险控制是非常必要的。一些教科书或文章建议混沌工程直接投入生产。这个理论没有错。所有的实验都是在生产环境中进行的,产生的报告很有说服力。但是,在生产环境中进行试验会带来高风险和高人力成本。如果不涉及任何一方,他的服务就会出错,可能导致现网发生严重事故。一旦实验超出了我们的预期,就有可能给业务方造成无法接受的损失。1)风险控制腾讯游戏的做法是每六个月左右在生产环境进行一次集中的大规模混沌演练。更多的失败发生在暂存环境(预发布环境)中。因为预发布环境的配置与生产环境基本一致,所以我们在准生产环境进行实验,数据的可靠性也有保证。在实践中,我们发现很多问题都是在预发布环境中提前暴露出来的。我们在预发布环境中发现了很多问题,这些问题很早就被解决了。比如游戏中有一个很大的体验服区。我们在体验服的实验只影响体验服的玩家,不会影响现网的大量玩家。所以一旦出现问题,体验服的玩家就会反映服务有问题,我们可以第一时间发现系统中的一些隐患。所以我们的很多实践都是在预发布环境下进行的。我们也进行了自动化实践。每发布一个版本,我们都会自动进行混沌演练。腾讯一般都有专门的练功环境,与现网完全隔离,大家可以随时随地在上面发起混沌练功。这个练习环境非常方便我们开发、测试、运维的同学们做练习。目前,通过对各种环境的管控,我们实验的风险得到了很好的控制。2)实验保护实验风险控制不够。我们希望有保护底线的能力,包括我们实验性的保护能力。在实验保护方面,我们的做法是根据稳态指标配置阈值。我们将收集业务稳态指标。如果没有,我们会提供Prometheus让用户主动上报稳态指标。我们根据稳态指标配置阈值。当指标达到阈值时,将触发警报。收到警报后,会触发一个钩子,钩子会终止实验。这样,在极端情况下,可以自动终止实验,从而有效控制风险。2.自动化实验上面提到的游戏版本,包括游戏商业化和活动部分,发布速度非常快,可能一两天就发布一个活动。如果每发布一个活动或者每迭代一个版本就做一次混沌实验,成本会非常高。因此,我们将混沌实验与我们的DevOps流水线整合在一起,开发者每发布一个版本,都会自动调用混沌平台的包来执行。这样无论每次何时何地发布版本,都会自动引用并执行实验,大大降低了我们实验的人力成本,提高了实验效率。3、红蓝对抗做混沌工程的初衷之一是为了提高团队的反应和协调效率,也就是我们组织的战斗力。事实上,一个团队缺乏提高自身效率的动力。腾讯游戏的方法是进行红蓝对抗。一个团队攻击和另一个团队的服务对抗,看这个团队的服务有多可靠,然后在小范围内公布它的攻击结果,这样我们就可以防御方自己的破绽提前暴露。红蓝对抗有效地实现了团队间的混沌工程。以这种方式运行可以获得更好的回报。4.实验内容我们做了一年多的混沌实验,那么我们做了什么样的实验呢?下图抽象了一些具体的实验项目。每个业务和系统都有自己的特点,上图只是一些常见的项目。1)单点故障通过杀机、杀pod、杀容器来检测故障隔离、切换准备、健康探测、检测等是否有效。2)告警验证通过实验触发告警,看告警是否能得到有效处理,以检验我们机构的响应机制。3)强弱依赖通过混沌工程,发现不合理的强弱依赖关系。我们有时会发现一个配置管理端的故障可能会导致现网玩家接入出现问题,控制面影响数据面是极不合理的。我们可以通过混沌工程检测出很多这样的不合理依赖,从而验证我们服务架构的合理性。4)网络抖动我们经常在现网做一些网络抖动实验。当用户访问我们的服务时,链路很长,一些丢包和抖动是很常见的。所以,测试我们的客户端或者整个架构能否容忍网络上的一些小抖动,是否有快速失败和重试的策略,也是我们演练的一个重要目标。5)机房故障虽然机房故障是小概率事件,但是整个机房宕机不可用的情况还是有可能发生的。我们需要用混沌工程做一些整个机房不可用的实验来验证我们的服务在其他地方是否可用。灾难恢复能力。6)第三方故障我们使用第三方服务,其质量可能不受我们控制。这些第三方服务是否有降级、熔断等策略,如果不可控,是否有本地缓存??等,都可以通过混沌工程来验证。7)过载保护一些黑产可能会对我们的服务进行一些恶意攻击。我们的混沌工程可以模拟攻击,主动检测我们的服务是否具备防刷流量控制的能力。以上是一些常见的实验内容。当然,每个业务都有自己的特点,这里不再赘述。互联网行业的变化是永恒的,我们的架构版本一直在变,我们的平台也在不断迭代。以上只是我们去年的一些初步实践经验。>>>>Q&AQ:混沌工程不断制造故障,监控告警不断触发。如何在短时间内终止运营?能否分享一下不可控故障即时自愈和监控即时恢复的过程?A:这一点就是上面说的实验性保护能力。我们平台会采集业务QPS、时延、同时在线人数等稳态指标。在进行实验时,用户可以根据这些指标配置告警阈值。比如我们的并发在线人数下降了20%,达到了阈值,我们的故障预防策略就会生效。当然,这不是立竿见影的。可能需要两三个循环,比如连续三个循环,才会真正触发本次实验的保护,自动停止实验。