随着数据化和信息化浪潮的深入,系统的架构在不断地演变,实现了从“单线程”到“多线程、多组件”再到“分布式、微服务”的一个跨越。目前国内外中大型企业基本都采用的是分布式系统架构,复杂程度高。机器是异构的,不同的机器厂商,会出现配置不同、运算、存储性能不同、网络延迟、带宽不同的情况。业务系统是分布式的,中间件也是分布式,网络也会有各种各样的节点,我们没办法去保证每一个节点它都是绝对可用的。这里面的任何一环出现问题,都可能引发系统故障。
2020年,新冠疫情使得实体经济遭受重创,倒逼各行业加速进行数字化转型升级 。随着人们消费习惯的变更,数字经济开始崭露头角,不断扩张的庞大用户群体在一些特定的场景下同时涌入系统,对分布式系统稳定性发起更高的挑战,导致故障频发。
国外亚马逊、谷歌云都曾挂机过,天猫双十一系统故障甚至上了微博热搜以及央视报道,就在2021 年,滴滴早高峰也出现系统问题,就连美联储也逃不开系统故障。这些事故都在说明一个事实——目前大多数的企业和组织并没有找到合适的系统故障应对方式,多数仍旧采取被动防御的方式,结果往往不尽如人意。那么究竟该如何保障庞大复杂的分布式系统的稳定性,走出故障频发的困局呢?
毛教员对中国的影响源远流长,他“积极防御”的战略思想,是指导中国革命战争全局与国家军事斗争全局的根本战略思想,奠定了中国稳定长足发展的基石。这对于我们来说有很强的指导意义,不同的是我们的斗争对象是系统故障,目标是保障系统稳定。
《矛盾论》和《实践论》是毛泽东思想的精华凝聚,先来回顾一下:矛盾论主要讲的是矛盾具有普遍性与特殊性、主次矛盾以及矛盾的主次方面;实践论主要讲的是实践是认知的来源与发展动力,实践也是检验认知的标准。
分布式系统的稳定性保障本身就比较难,再加上高峰流量场景,比如常见的双 11 或者是突发疫情导致行程卡的访问比平常多 20 倍的情况,我们该怎么保证系统的稳定性?想要解决这个问题,首先要去识别它的主要矛盾和次要矛盾,进而再去改变不稳定的现状。那主要矛盾是什么?我们又该怎么做到“积极防御”呢?
笔者认为这个主要矛盾就是超大流量冲击超复杂的系统,依旧靠单点去做评估,要知道仅从单点去突破,没有从全局去考虑就没有把握能取得全局的稳定性。
“积极防御”当然这不是嘴上说说就行的,具体还是要进行实践。我们可以向安全行业取取经,“现在的安全是以合规作为检验标准,比如某个单位有没有安全设备,如果有了是不是代表有安全的能力?安全讲一百遍不如打一遍。”360集团董事长兼CEO周鸿祎在某次国际论坛上表示实战应该作为检验能力的唯一标准,而他所说的打一遍就是要对线上系统做攻防演练。同理系统稳定性保障也是如此,主动进行峰值流量系统全链路压测、容量演练是解决主要矛盾的关键一步。
先来看一组数据,2017年故障时长1106min到2020年的0min,这是怎么做到的?
今天就借用物流行业的一家企业实践经验来告诉大家如何构建积极防御体系。该企业从2017年开始发展快递业务,到2021年Q3, 收入从70亿快速增长三倍到现在的200亿,随着业务的不断扩张,企业的IT系统也在经历着天翻地覆的变化,为了保障业务的稳定发展,系统的稳定性保障也逐渐从被动防御转向积极防御。
2017年他们采用的方式是搭建性能测试环境进行系统压测,可耗费了大量的人力、硬件资源成本,最后得到的效果还是差强人意,当年双十一0点系统还是出现了故障,崩溃2小时导致无法接单,损失惨重。由于测试环境的差异性,一些故障只有在线上才会显现,当出现故障后再进行排查定位修复这就是被动防御,无法保障系统持续稳定可用。
意识到问题所在,他们想要参考阿里双十一,采用生产环境来做全链路压测,主动进行生产环境系统稳定性验证。这里就遇到了一个核心难点——实现数据隔离,阿里采用的是通过改造中间件实现压测数据的识别和转发到影子区域的方案,可这并不适用于所有的企业。许多企业与该物流公司一样存在中间件不统一、人才储备稀缺、成本考量的问题。
最终他们采用了市面上成熟的开源产品Takin,利用JavaAgent字节码增强技术,无需改造业务系统,从JVM层面来实现压测数据的识别和转发。只要装了Takin的 Agent 探针,压测流量自己就会乖乖去到这个影子库里面。当然还有一个很重要的东西,如果我是一个支付请求,我不能把压测请求转发到支付宝或微信,Takin的挡板功能就能帮助拦截。此外也有一些 job 或者 check job,只要安装了探针,也可以虚拟出 job 的影子进程去做这个事情。
平台工具只是实现目标的一个手段,具体的实施过程其实非常重要,也会影响到最终的保障效果,生产环境全链路压测在实施中有6项关键性的工作。
压测是一个团队协同配合的工作,演练一方面是演练系统,另一方面是演练整个组织的这个应急反应的体系,所以基本上整个过程 IT 团队的每个角色基本上都要参与进来。
通过生产环境全链路压测该企业在硬件资源投入方面减少了63%,在人力投入方面减少了65%,也达成了双十一高峰期间的系统0故障的目标。
前面一直在讲通过演练去确保双 11 流量高峰系统没有问题,解决了主要矛盾,接下来要解决的次要矛盾了。业务量大、业务流程复杂,系统每天都要做发布,那怎么确保发布之后系统是没有问题的?或者说如果某个laaS层或者 pass 层的组件出了问题,怎么确保核心系统都是 OK 的?快递公司系统是 7 * 24 小时的运作的,并不是每一个核心服务都会持续有流量,以订单服务为例,白天流量会比较高,但到晚上就不高了,因为下订单的人都睡觉去了,而像中转服务它晚上才是流量高峰。曾有过这样的尴尬,晚上系统订单服务做了变更,到了第二天早上流量才 100 它就出现故障。很多时候可能都是这种非500或者非200的报错,甚至个直接抛一些 error 来,它并不是业务逻辑的错误。为了减少发布之后的系统意外,利用Takin中Agent的数据隔离能力,实现了真实流量在跑的时候同步进行巡检,此外利用测试流量进行7*24小时的业务巡检。通过设定响应时间、成功率去做系统监测,当实际响应时间/成功率超过预设值时,巡检系统就会发出提醒,服务飘红/飘黄。
总结一下,巡检就是把非业务逻辑的报错,通过技术相关的指标给直接反馈出来。后来该企业还基于巡检以及TakinAgent在生产环境实现了混沌工程,主动模拟注入故障来进一步检验系统的稳定性。
安全领域有个“零信任”理念:永不信任,持续验证。简单来说就是认为你每一次访问都是不安全的,然后不断地验证你的行为。映射到系统稳定性保障领域,当企业具备这种主动验证系统稳定性的能力,验证的次数越多,你收获的价值就越大。提前发现系统问题并解决,才能有效地保障业务的连贯性,同时能够将更多的时间投入到解决业务的问题上,积极防御的效益可见一斑。
文中提及的Takin产品核心代码已在Github上开源,有兴趣的可以自行了解。
开源地址:https://github.com/shulieTech/Takin
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。