[关闭]
@gaoxiaoyunwei2017 2020-12-01T08:02:16.000000Z 字数 8818 阅读 413

磐石双体系:腾讯金融运维平台实践-谢海林

公众号


磐石双体系:腾讯金融运维平台实践-谢海林
一、项目的背景
二、整体解决方案
三、统一变更体系
四、故障处理体系
五、磐石运维未来思考

image.png-1015.3kB

作者简介:谢海林,运营开发12级专家工程师,腾讯金融运维平台团队负责人,从“零”开始打造了金融级高可用磐石运维平台。随着支付业务的发展,磐石运维平台也一步一个台阶,在满足业务需求的同时,逐渐形成了具有金融特色的运维平台。

一、项目的背景

今天在这个会场,有不少人讲了很多的体系化,要把整个体系做完整,是一件很不容易的事情,我做个小调查,这里面超过50人团队做这件事情的举个手?没有,我们团队只有十几个人来做这个领域的事情。所以我们首先要思考,这么大的体系里面,什么东西是最值得我们去做的,到底是做发布、做扩容、还是监控,还是做容器化?一定要找准和业务切合的发力点。我今天主要和大家分享我们找了那些点,同时在做这些点的时候,我们碰到了什么样的问题,以及是如何解决的?但是提醒一下,可能在你们业务上面并不管用,这可能需要你自己回去找这些点。

image.png-400kB

首先,交待一下我们的业务背景。经过2014年的红包之战之后,绝对算是海量业务,在春节大概有十万级每秒的支付,有百万级每秒的入帐,平时每天的量大概也有十亿级别,这是外面可以感知到的支付的情况。在这个背后的系统数量非常多,服务器也有好几万台,每天的日志量更是几千亿到上万亿的级别。

其次,互联网业务有一个特点,它是在奔跑中去更新迭代,所以变更也非常的频繁。但是我们用户的要求是非常高的。比如说坐地铁,你不能让我等,我等不了,所以200毫秒以内必须要返回,同时要可用,同时资金不能出现问题,实时要看到资金的余额和流水。举个例子,在春节抢红包,有的人因为抢了2块钱的红包,他就会觉他的流水是不是到了,如果没看到流水,他就会不加思索的来投诉,这就是我们的用户。

第三点,平台依赖的东西没有什么是100%正确的。硬件不可靠,程序有bug,人也会犯错;

二、整体解决方案

在这样的场景下,对于运营平台来说,或者是对于做运维的同学来说,平台的要求是什么? 老板只会说一句话,不管我们怎么干,只要不不出事就行。我们的对应思路就是:全方位兜住不确定性,全方位降低未知风险的影响。那我们怎么做到不出事这个事情呢?我们是这么来思考的,首先需要定义我们需要解决的问题。

image.png-359.7kB

定义了问题之后, 我们建立了3个针对性的三个平台来解决。

image.png-343.9kB

一切都是为可用性,这也是我们和其他团队不一样的地方,因为支付的要求非常高,成本不重要,效率不重要,重要的是不要出事。

有了整体的解决思路之后,我们也就有了整体的解决方案,我们把它叫磐石,希望能够让这个平台稳固得像磐石一样,能够给大家提供不间断的服务。 接下来,我们讲讲这两个体系里面,到底是怎么去做。

三、统一变更体系

统一变更,业务无损变更方案,控制变更时不搞出故障。这个过程中我们如何思考的?这是我们整体的解决方案,说起来很简单。

image.png-378.9kB

第一,统一系统化:有没有哪一个部门、哪一个团队真的不再登录服务器的?我们做了这么多年,现在依然没有杜绝这件事情,依然有人还需要在个别程序上去动服务器,希望有一天,通过我们的努力,我们运维不在登录服务器,所有的变更都是通过流程审批、通过系统工具执行的。

第二,统一灰度:无论你做任何一件事情,都要走灰度,具备一步一步放开的能力。

第三,统一回退:在发过过程中有任何问题,先不考虑原因,快速回退。

第四,一致性(发布即生效):我要让我的发布是符合预期的,我们把它叫一致性,发布即生效。

第五,变更记录:所有的发布记录是可追溯的。

在这个过程中,我们是碰到过不少困难的。首先说第一个难点,如何确保变更时现网影响可控?

image.png-579.1kB

我们的答案是统一灰度,我相信很多同学都会去做灰度,我们有什么不一样?我们做灰度的时候有几个特点:

  1. 按照业务优先级逐步灰度。QQ支付的量比较小,所以我们就先做QQ支付,再做微信支付,所以业务是按照优先级。
  2. 流量逐步从小到大的逐步灰度。从第一步开始一直到慢慢开始往上升,直到所有全部灰度完。这里面难的部分是,你做完一步之后,怎么验证这一步真的就没有问题,现网业务就真的没有影响?这里面非常的复杂,包括自动化验证、智能巡检等等一系列的东西,由于时间关系不一一讲解。
  3. 一个步骤内只动单边。保证左手出问题的时候,能切到右手。

同时,我们在统一灰度变更中有3个兜底能力:

  1. 流量切换到对端。如果这个真的坏,也没有关系,能够切到对端去。
  2. 版本回退。这个过程也是有灰度的。
  3. 版本基线回退。就是回退搞不定了,切换也搞不定了,那我们就强制恢复到昨天晚上的版本。恢复业务,建这个能力以来只用过一次,就真的是救命工具。

是不是做灰度能够解决一切问题,我不知道大家出现过这样的问题,昨天A同学发了一个版本上去,现网没有重启;第二天B发了一个版本,然后重启了服务(导致A同学的版本生效了)就发现出问题了,结果就回退,回退没效果;B同学就慌了,这是什么鬼?原因是A同学的版本导致的问题,B同学完全不知道昨天A发了版本还没有在现网生效,这就给定位带来了难度。所以,发布和生效是不同阶段的事情,怎么做到”发布即生效”,不留坑给后面的同学。

image.png-516.9kB

我们首先看一下我们发布的全过程,从流水线中心,然后到发布中心,然后到IDC现网、然后做IDC现网基线,最后到发布中心基线,一般的逻辑是这样的。

我们的一致性上在实时核对的方案做了以下几个事情:

每次发版本的时候,都要确认线上的版本是不是上一次发的版本,如果是,证明现在的线上的版本没有被污染过,这能够很好地杜绝因为别人不小心而导致问题。

重启完了之后必须做业务生效和异常检测。这部分主要是通过自动化验证,包括重启生效检查,包括业务巡检。这个逻辑做完之后,最起码保证特性发完之后就要生效。

生效之后,合入本地基线库,要去做本地合入基线检查,确保本地备份是可以的,然后再去合入远程的基线库,合完之后又得去做一次远程的合入检查。
以上的三个核对步骤,总体思想是:下一个步骤确保上一个步骤的正确性。
做完这个之后,我们还做了离线的核对。因为实时流程只能保证每次按这个流程走的时候,那有的人就是不守规矩,把这个地方改了怎么办?虽然很少,但是依然有,因为有的人心急,或者是他的习惯没有改过来,所以还有30分钟一次的核对,保证把现网的IDC的目录、现网基线的目录和发布中心的目录做三方核对,保证他们是一致的。

总结一下,在实时发布流程中,我们在每一次下一个步骤都要确保上一个步骤是正确的,这保证了我们的预期和执行结果是一致的。在离线核对的方案中,保证非正常的流程的一致性,包括漏发、机器故障、手动修改、入侵,这些都能够在离线核对中兜住并发现。这个解决方案能够给我们带来非常大的收益,让我们不再出现意料之外的不一致。

接下来再讲一个难点,运维平台自身怎么保证高可用?对于发布来说,发布平台有时候就是救命的,假设深圳哪天灾难了,就是要发布去把上海所有的机器修改一下配置。发布系统用不了,那就尴尬了。所以业务上做了双城双中心,我们也做了双城双活,我们怎么做的呢?也很简单,从前端到服务层,再到存储层,再到外部的系统都有所针对性的设计,我们的要求和现网一模一样。

image.png-510kB

第一,在最外层看话,用“三个域名”全部可用,比如OP,在深圳是深圳OP,在上海是上海OP,3个OP域名是完全可以用,用哪一个都可以。这有点LOW,但是非常有效。

第二,我们在网关做了什么事情呢?我们做了双层的路由,但是本地优先。所有的无状态服务调用的都是本地化,有状态的服务,在服务这一层我们做了读写分离,读本地,写第三方,我们的假设前提是,正常情况下是不应该3个城市里面同时出现2个的,所以读写分离,读本地,写第三方城市。

第三,DB这一块,我们也有一个DB集群,我们叫MySQL集群,三地两中心的概念。

第四,外部系统,所有的外部系统必须本地依赖,万一第三方有问题,全部降级。
总体来说,这里的细节比较多,我们在这上面花了大量的时间和精力。

四、故障处理体系

故障是不可避免的,我相信所有做运维的同学都知道对于故障处理,老板的要求就是一个子,快,最快速处理故障方式恢复业务,减少业务影响。 具体到我们这边,我们是这样想的,一个故障发生,有两种可能:

image.png-420.8kB

第一,这个故障经常发生,比如说机器挂是经常发生的,这叫高频已知故障;这部分,我们希望能够做到系统自愈。系统自愈是给到开发的压力,你的系统架构必须去支持自动切换这件事情。

第二,如果高频已知故障可以自动切换,那是不是所有故障都能够切换就行了呢?不可能,所以运维要解决的是其他故障类型,以及故障自愈不成功的时候,人为要介入处理故障,我们希望一键故障恢复,一键能够把事情处理好。自动切换解决高频已知故障,人工切换兜底所有故障处理。

对于运维来说,主要做人工处理故障的部分。因为自动处理那是开发架构要支持的,那是开发要解决的。我们如果来确保人工处理故障的高效?我们是这么来思考的。

image.png-407kB

第一、发现故障,第一时间发现有故障。
第二、定位故障,辅助系统负责人快速定位故障的原因在哪里?
第三、故障处理,辅助系统负责人快速恢复故障。
第四、故障复盘,把发现、定位、处理的问题逐步完善,持续迭代。
第五、故障演习,怎么确保故障处理的时候,是不是真的有效?

这里面难点在什么地方?我理解有四个。

海量数据又快又准,前提是数据系统本身稳定,在这个过程中有一件事情是很难解决的,作为一个开放的监控平台,有的人就是不守规矩,给你乱报数据,例如把一个纬度值上报特别不合理,在我们这样的平台下,上10亿级的用户,你分分钟就会挂。那怎么办?

image.png-408kB

我们做了一个旁路纬度值的监控,通过实时的数据流,一分钟级的反馈,实时数据流能单独统计一条这个纬度值报了多少量,在一分钟内的膨胀数有多少,如果这个很大就直接屏蔽掉,这就是我们的做法,既简单又粗暴,非常的有效。我们现在配置的单纬度值不能超过5万,超过5万就立马过滤掉。在这个过程中上了之后,发生了非常多次纬度值上报的异常,并且发现了超级纬度值异常的情况。我们作为平台要有平台的原则,就应该大胆跟业务说这样是不合理的,业务方必须整改。

海量数据又快又准,其实时效性与稳定性是挺矛盾的一对,那我们是怎么做的呢?

image.png-487.3kB

一方面对于监控数据,希望时效性是很高的,例如秒级、1分钟级;一方面又希望数据完备性是很好的。我们的解决方案是:模拟自动化上报核对方案。

每一个时间点开始,都上报一条测试数据,在每一次用的时候,会去看这批自动化测试的数据是不是到了,如果到了就认为之前的数据都可以用,没有到就不能用。这是个取巧的方案,但是效果非常好。在这个方案之前,我们使用的等待方案,一分钟采集、一分钟统计入库、一分钟等待,一分钟的数据到真的对外提供准确的数据是3分钟之后,这对于业务来说是很要命的,采用新方案之后,我们的平均可用时间,从原来的3分钟到1分30秒,1分30秒的时候大部分的数据都可用了,只有少部分数据不可用,不可用的时候就告诉用户说现在不可用,但是90%的数据都可用,而现实的情况是这90%的用户才是我们的核心用户,所以大家感受到的时效性就提高了非常多。我个人觉得这个方法没有多复杂,但是是特别有效去解决了我们的问题。

接下来再来看我们的告警处理。我想做一个小调查,小于50条的举手?大于100条的有没有?我相信还有很多人没有举手,可能是大于500条。 基本上,一个运维人员的极限的处理,一天50条。超过50条,这告警一定无法准时有效处理的。50条以上还能够实时看,那我就服了;所以我们的目标定在10条。如果一个运维人员1天只收10条告警,还不去看,那说明人有问题,可以处理你。但是如果告警超过50条,老板还要求你每天看,我觉得你可以趁早考虑换个地方,因为你肯定做不到,某天背锅的就是你。

告警要么配不全,要么就漏,要么告警就很多,那我们怎么来解决这几个纬度的平衡呢?

一般告警配置,是算法阀值+时间长短这两个维度上来平衡误告和漏告,这里有挺多历史发展进程的。

接下来又有AIOPS2.0,2.0是把1.0做成离线的部分做成实时的,我们把开源算法拿过来,省掉了训练算法的部分,发现效果还不错。

好景不长,我们接下来又发现了一些新的挑战。

image.png-721.6kB

1、非常明显的故障,为什么要用拉长时间的方式告诉我呢?比如说业务挂了,还等了3分钟才告诉我,等3次识别异常才告诉我,这是否合理?业务觉得不合理,业务都挂了,为什么一定要等3分钟才告诉我?这件事情迫于压力变成了一次告警,这有引入第二个问题。

2、稍微波动一下就告警,我晚上还睡不睡觉?
那我们怎么来进一步解决问题呢?

我们在AIOps2.0的基础上做了一个优化,把整个数据异常的判断,从单个点的判断变成了影响面积的判断,通过时间和空间两个维度来做,如果大的故障就可以很短时间告警,如果失败率标得很高,那一分钟一个点就出来了,如果很低可能稍微长时间一些。

所以我们要看影响的面积,超过就立马告警,如果没有超过就持续计算影响,直到影响的范围超过预定范围再告警。

这样很好的解决了:第一,这个区间的范围放小之后,能减少漏报的可能性;第二,时间范围放大,可以把时间放更长一些,提升准确性。所以,它能够解决大故障很快发现,小故障是用时间来换取准确性。告警的准确性和时效性矛盾得以解决,告警漏报性和准确性矛盾也得以解决。

这里还有人工的部分,就是是要配敏感度和时间,也就是要知道影响面积,面积有没有办法自动算呢?进一步思考,业务故障是有定级标准的,如果你达不到这个定级标准就能发现,就说明我们提前发现故障的能力不错。 所以,我们通过故障处理时间的SLA和故障事故规范管理办法来确定面积,比如说支付,100千笔以上的影响必须发现,那我在50比的时候发现,那就很好了,不一定非要在第一笔失败就发现了。

做完这件事情是不是就可以了?还不行,为什么?因为我们还有问题。为什么下线了一个集群,一直没有告警?今天业务搞个活动,怎么一天都在告警?这种能否进一步减少告警?

image.png-502.5kB

我们的做法是,在刚才的面积算法之上,还加了一个典型的故障处理,典型的业务异常算法。典型业务异常算法是我们根据经验给做出来的,新业务、扩容、缩容、切换场景等,我们一个一个检查,如果说满足了这些场景,告警降级,同时在通知里面告知他说可能是因为什么原因。

最后我想说是,告警发现这件事情,业界做了这么多年,也没有得到最完美的解决方案,因为我们永远做不到一个故障就告一条警。

那到底做到什么水平就可以了呢?我们想到的是,如果告警每一条都是有效的,每一条告警是有人去跟进和处理,这就是做得好、做得有效了。

image.png-398.8kB

所以,我们现在做了一个告警跟踪,当告警发生完之后,如果是立马要处理的,马上通知人处理,处理完之后业务恢复,告警处理完成。这个时候,人去手动标注告警的结果;如果说告警是低优先级的,就先持续关注,如果说一段时间还没有恢复,就升级到高优先级告警,如果自动恢复就自动做一个标注。这样有一个好处,你可以很好地去评估告警的准确性,你知道今天发出来的100条告警,到底哪些是有用的,哪些是没用的。

接下来讲告警的定位,定位这件事情很复杂,因为这件事情很难,特别是对复杂业务。
为什么难?调用多,调用链条长,部署复杂,运维系统割裂,我们一路走过来,这些现状都是存在的。那怎么办?
过去的告警定位方法,人站在中间,周围给了他一堆的工具,极度依赖人。你会发现,运维人员也挺乐意这种方式,甚至是高兴、自豪,为什么呢? 他定位出来了,另外一个人没有定位出来,说明这个定位人的水平高。但是这不能普及,那我们就是要解决人的问题,想办法变成一种系统方法。

image.png-388.1kB

我们设计了一种思路,我们把它叫双向分析法。
对一个故障来说,第一是看对外的影响是什么,向上去分析影响;第二是向下分析故障出现在哪里,故障点是哪一个地方坏了,坏了之后就拆掉,所有的分析方面都是以快速止损为目标,向上分析影响的时候,是提供决策依据,是否开大招,向下定位故障初因是什么,不去分析根本原因,只要知道故障源,知道这个地方坏了,就有办法处理它。

在系统故障的时候,系统多处指标异常,到底是哪一个纬度的原因呢?这个要找到不容易。

image.png-1025.4kB

我们的做法是,化繁为简。具体做法是,无论你的里面多复杂,在宏观层面看就分几个层次,每一层又分成几个机房,或者是几个区域,每一个区域、哪一个地方有问题,我们只要找到这个区域就可以,我们把一层的一个区域叫做集群,只要找到集群,我们就隔离掉这个集群,这就是我们定位和处理的逻辑。我们把非常复杂的图变成了简单的模块和功能。

向上评估怎么做准确?我们只分了3层,底层、中间层和入口层,我们对向上评估的时候就看入口层的影响多大,把入口层全部找到,然后进行数据清洗,清洗完之后留下有影响的一些点是什么?有影响的这些点,把真正对用户有影响的功能选出来,并且计算它的影响是多少?供业务方决策。

其次去分析故障源在什么地方?我们有没有一招致敌的办法?我反正是真的没有。所以我们都是人工判定故障源,通过人的经验,比如:底层比上层优先级更高,如果说都报错,底层更有可能是影响源。这里很多都是有经验的沉淀,包括网络、负载、中间件、也包括银行、商户、可开放的接口,依据人为经验确定定位逻辑,尽可能保证向下找故障源是相对准的。

接下来要处理故障,怎么让这个处理足够的简单?我们是不是具备的故障处理的能力?

image.png-338.8kB

我们有一个容灾白皮书,首先梳理清楚系统架构,然后针对架构中每一个集群,要么切换,要么摘取,从IDC、SET,IP、CITY几个层次都考虑,这个过程说起来容易,但是真的要实施到每一个业务没有这么容易。比如对于支付的场景来说,加起来有六七十个工具,当然还有一个前提是系统架构本身是支持的。

有了容灾工具,还要保证它有效,我们觉得有效的方式就是用,不用肯定就没效,通过演习来保证有效。

image.png-528.7kB

故障演习依据不同的级别和场景,制定不同的异常类别,确定不同的时间周期。尽可能在平时就用一用,这样才能确保关键的时候是可用的。例如:支付是每一个月做一个机房的全网容灾,机房每半年做一次,开关级的每双周做一次,这里面要投入大量的工具和人力,但是我们认为这件事情是值得的,功在平时,这件事情做了之后,才能保证真的哪一天深圳挂了,敢切到上海。

是不是这些都做完了,就没有其他的了,我理解并不是这样,我们可以进一步提升效率,降低中间浪费的时间。

image.png-576.6kB

所以,我们做了运维管家,这是进一步解放运维人员和开发人员,让负责人按照唯一的处理的路径一步一步往下,这样尽可能减少人决策和犯错误,同时进一步降低对人的依赖。

五、磐石运维未来思考

由于时间关系,今天我们就大致讲了下我们这2个体系的做法,其他部分有机会下次在分享,最后发2分钟时间说一下我们未来的思考。未来我们要做什么呢? 下面这张图是我们规划的全景图。

image.png-489kB

我们要体系化平台化构建运维的服务能力。这是我们去年做的整体的规划,整个运营平台,或者是运维这件事,首先思考的是运维服务能力到底交付什么?比如说我们规划的交付是统一值班、持续运营、运运维服务度量、运维交付流水线。

逻辑层也主要建设运维PASS平台能力,包括故障处理体系、一变更体系、容量管理平台和SRE开放平台,为什么要开放平台?因为只有开放平台怎么去解决个性化。

最底层是基础设施层,运维配置中心、流程引擎、操作通道、数据通道。我最后是管理设备agent。

在体系上我理解不会有太大的变化,未来我们更多的在价值维度的思考:

第一、希望这个平台的能力是具备接入及服务的能力。对于我们的业务,只要进了磐石平台,就应该享受磐石运维能力交付的能力,这需要我们去结合效能、基础组件等。如果这些东西没有搞好,衔接不上的话,要花大量的时间去补缝隙的地方,所以最好是能在一开始把研发流程、技术组件和平台整合起来,这是最好的。 只要你接入,最少运维能力就有60分。

第二、平台开放的能力,如果这个运维有追求,想做的更好,是可以通过自己的努力,在平台上自助做到90分的。

第三、智能化,进一步解放人、也可以说是不依赖人的事情,应该也是需要持续去做的。

总后,在说一点,运维这个行业,选择运营开发这个岗位,一定要能够跟你的业务痛点结合起来,找到你业务的痛点价值,才能做好这件事情,如果按照业界的思路去搭,去大而全的攻,只能忽悠一段时间,大家都明白之后,就会作死。运维最痛苦的是心理压力太大,可能不是真的很累,做任何一件事情都很累,运维真的是心累。所以我们任重而道远,一定要通过技术的手段,彻底解放运维同学,这是我们的使命。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注