无人值守时代,运维如何保障发布质量?

导读:阿里巴巴千亿交易背后,如何尽可能避免发布故障?在面对实际运维过程当中遇到的问题该如何解决?近日,在GOPS大会上,阿里巴巴运维技术专家少荃,给咱们带来了解决方案和思路。java

clipboard.png

做者:陆叶平(花名少荃),阿里巴巴研发效能事业部技术专家。目前从事运维中台(阿里内部叫诺曼底)建设方面的工做,是集团内最大的应用发布系统(海狼)负责人。算法

前言数据库

近几年,咱们在发布效率和稳定性方面作了很多工做,其中效率简单的说就是发布耗时,一个是发布的速度,好比一个应用是1个小时发布完成,仍是5分钟发布完成?另外一个是人员介入,开发在发布过程当中是否须要介入处理各类发布过程当中出现的问题?这二者都作好了,才能说是发布效率提高了。稳定性最基础的是系统的稳定性,保障系统的可用,而最关键的是要保障经过系统来进行发布的应用的稳定性,不会由于发布而致使服务不可用等故障出现。安全

效率这块咱们在集团内比较受好评的产品是SP2P的文件分发系统,叫作蜻蜓,咱们根据阿里自身的一些特色,实现了一套安全高效的P2P分发,同时在P2P的协议上引入了超级节点,就是S,提高了P2P网络的启动速度,目前已经开源。稳定性这块咱们去年作了一个产品,叫作无人值守发布,对发布进行检测,看看发布是否会引发问题,来提高发布的可靠性,今天就和你们一块儿交流下这方面的心得。网络

线上发布之痛

咱们为何要在稳定性方面投入大量精力呢?先让咱们来看一个笑话。架构

变动故障运维

clipboard.png

这个笑话可能没那么可笑,可是它真真切切的说明了一个问题:理想和现实的差别,你觉得是有四个单身狗陪你,可是实际倒是另外两对情侣。这个和咱们作生产环境的发布是同样的,咱们觉得凭借咱们出色的逻辑思惟能力,已经把全部场景都想到了,测试也作的很充分了,可是,发布上线后,常常会遇到实际结果和预期不一致,故障发生了。咱们针对阿里的故障产生缘由作了统计,其中很大一部分都是线上变动引发的,相信在座各位也会遇到或者制造过故障,开发和运维的同窗对故障都是很敬畏的。机器学习

故障你们都遇到过,可是故障的影响差别会比较大。有些故障多是故障发现后处理了一会就恢复了,有些故障则可能会致使严重的后果。因此咱们须要尽可能避免变动带来的故障。单元测试

业务挑战:阿里的特殊业务场景学习

回到阿里,咱们都知道,去年双11的成交额已经达到了1682亿,想象下,这么大的交易额下,若是出现了故障,那会怎么样?

阿里如今的业务多样化发展,新零售、线下支付等一些新的业务场景,要求咱们对故障更加敏感,要可以更好地避免故障,更快地发现和处理故障。想一下,若是是线下场景,好比用支付宝坐地铁,若是出现几分钟的服务不可用,那会怎么样?

如何才能有效的避免故障发生呢?

那么,如何才能在发布的时候有效的避免故障发生呢?

靠“蒙”?你们知道确定不行。但是细想一下,不少时候确实或多或少在“蒙”。我我的是有过相似感觉的。咱们虽然不会随便到不通过测试就进行线上发布,可是虽然已经通过了多轮测试,确定仍是没有办法覆盖线上各类复杂多样的场景的,而这些没有办法覆盖的场景,就只能靠运气去"蒙"了,运气好的,这些场景没有问题,运气很差,恰好就其中一个场景出问题,出现故障了。

clipboard.png

一般来说,为了尽量不要去“蒙”,咱们会对上线流程加入各类验证环节,来保证发布尽量可靠。例如发布前,咱们会经过各类测试来验证功能是否ok,包括单元测试、集成测试等,发布过程当中,咱们会经过一些发布策略,例如先预发(预发布是一种特殊的线上环境,和线上使用一样的资源,好比数据库等,可是不会有用户流量进来)、而后灰度、而后分批滚动发布等方式,逐步将变动更新到线上,发布完成后,又会借助一些故障预警系统,例如像阿里有GOC来尽早的发现故障,进行处理,这些环节的这些手段都已经有成熟的系统来进行支持,可是发布的时候,咱们经常仍是内心没有底。

"人工智能"的解决方案

那么,还有什么办法可以帮助咱们尽量地保障发布质量呢?你们可能都已经在作了:就是"人工"智能的发布保障。

clipboard.png

在发布过程当中,盯着各类屏幕,去看各类数据,来人肉的判断本次发布有没有问题。在阿里,这些屏幕包括:监控、发布单、机器、GOC故障预警等。监控可以反映出来当前系统的一些情况,例如机器的负载是否上去了,接口的成功率是否降低了,发布单则能让咱们了解当前的发布状况,有多少机器已经更新到新版本了,有多少还在跑旧版本,有多少机器启动又遇到异常了等等,盯着机器则能够看一些日志信息,是否有一些新的异常出现了,异常的量是否很大等等,GOC让咱们在故障发生的第一时间就能知道,结合本身发布的内容判断是不是本次发布引发,须要进行处理。

这种方式相比以前让人放心多了,是由于如今咱们看到的是最真实的线上环境的状况,而不是单单的测试数据。可是这种人肉盯屏的方式也存在着很大的问题,首先是成本过高了,发布过程当中须要有熟练工盯着各类屏幕去看,片刻不离,其次是人的因素太大了,一样的发布状况,不一样的人分析出来的结果可能彻底是不同的,即便是同一我的,由于状态或者其余方面的缘由,针对一样的一些数据,可能分析出来的结果也不同,另外,人也有局限性,各类数据刷新很快,肉眼分析的方式根本都来不及看。

既然这种盯屏的方式被证实是有效的,可是存在一些问题,那么咱们就考虑经过系统化来解决这些问题,因此,就有了"无人值守发布"。

无人值守发布

无人值守发布主要是把上述过程自动化、智能化。经过自动化采集这些实时的线上核心数据,进行智能化分析,迅速对发布情况进行判断,是否有故障发生,有的话则当即终止当前发布。

无人值守发布的两大核心能力,一个是故障检测,一个是异常推荐。故障检测主要是发现如今的问题。异常推荐主要是防范于未然,是指发布出现了问题,可是不必定会引发故障,这些异常给开发的同窗透明出来,须要开发注意,比较常见的是出现了一些异常,这些异常从绝对数量或者涨幅来看没有很是明显,但多是须要处理的。

什么是无人值守发布

clipboard.png

首先是发布单详情页面中的无人值守信息展现,发布单详情页面是发布过程当中最常会去看的页面,因此咱们选择把无人值守检测出来的一些信息展现到这个页面,在一个页面中把能够作的事情都作掉。固然,并非说开发同窗必定要本身去刷这个页面才可以知道当前发布是否有异常,当发布出现异常的状况下,系统会先自动暂停当前的发布,而后经过钉钉等一些通知方式,告知开发的同窗,你的某个发布出现了异常,须要你去看下。

这些展现的信息包括了左侧的当前发布是否有异常的概要信息,经过概要信息,能够知道当前发布有没有问题,若是有问题,能够看右侧的问题分类,是基础监控指标出问题了,仍是业务指标出问题了,或者是日志出问题了,日志出问题具体是哪一个日志有问题了,在这里均可以看到。

若是这里的信息还不够来判断是否发布有问题,那么点击查看详情,能够看到更加详细明确的异常信息,来进行判断。

无人值守发布的时候须要应用接入到无人值守发布系统,固然大部分状况下这是一个自动化的过程,系统会判断应用是否符合接入标准,若是符合,会自动接入,可是也有一些状况会致使应用没法自动接入,这种状况下,也会告知用户当前应用是否接入了,若是未接入,须要作一些配置或者改造来接入。

无人值守发布详情

clipboard.png

这个是无人值守发布信息展现的详情页面,在这个上面,能够看到更加明细的一些信息,好比异常数量的发布先后趋势对比,业务监控各个指标的变化状况等。经过这个页面,开发的同窗基本上有足够的信息来判断本次拦截是否有效,是否须要进行回滚等操做。

无人值守接入

clipboard.png

这个是应用接入无人值守发布的一个页面,主要须要配置业务监控指标、日志路径等。

无人值守的实战案例

clipboard.png

这是一个典型的案例,其中一些数据作了隐藏或者处理。发布过程当中日志中某个异常出现了大幅度增加,咱们能够从左侧看到异常的数量,点击异常信息还能够看到更加明确的异常堆栈信息,右侧能够看到异常数量出现了明显增长,下面能够看到这个检测被用户判断为确实有问题,最终执行了关闭发布单进行回滚的操做。

用户反馈

clipboard.png

这些是用户的一些反馈。应用接入无人值守发布,对提高发布的稳定性起了立竿见影的效果。

指标

上面这些案例都表明了一部分用户的感觉和反馈,那么总体效果怎么样,仍是要拿数据来讲话。

clipboard.png

业界对于异常检测这块有两个主要的指标:一个是召回率,一个是准确率。

召回率主要用来反映漏报的状况,准确率主要用来反馈误报的状况。漏报和误报的概念比较好理解。漏报就是原本有10个故障,系统报了9个,那么漏报了1个,召回率是90%,误报就是只有10个故障,报了20个出来,多出来的10个就属于误报,那么准确率就是50%。

目前准确率方面,咱们已经作到了60%左右,也就是说差很少每报2次,就有一次确实是有问题的,这种体验应该算还不错。

召回率方面,咱们已经作到了90%,这个90%是指出现了一次故障咱们没有报出来,咱们有效拦截了9次,这9次中可能会引发故障,也可能只是有问题,可是不会形成故障,可是由于及时发现了,都没有形成故障,很难明确说这9次里面到底有多少是会形成故障的,因此计算召回率的时候没有单独计算故障的召回率,而是把故障和异常一块儿计算进去了。

关于先重点抓哪一个指标,咱们也经历过一些波折。一开始的目标是拦截尽量多的故障,因此比较注重召回率,致使长期一段时间内,准确率很低,拦是拦了很多,可是误报至关多,报10次里面可能只有一次是有效的,若是咱们是用户,可能几回误报之后,就对这个产品失去信心了,这个致使咱们不敢大面积推广。后来调整策略,优先解决准确率的问题,反正没咱们系统以前这些故障也是存在,有了系统,能减小一些就是好的,因此先不追求召回率,把准确率作上去后,能够大面积进行推广了,受益面大了,避免的故障也天然多了。固然,后面仍是继续抓了召回率的。

无人值守发布实现

前面说了很多,可是都没有提到系统的具体实现,接下来咱们看是怎么去实现无人值守发布的?

首先看下咱们的产品分层和业务流程。

产品架构和业务流程

clipboard.png

咱们的系统大体分了三层,最上面一层是发布系统层,咱们的产品叫海狼,主要是发布单的提交、执行以及无人值守信息的展现和反馈,这一层是能够扩展的,除了发布系统外,也能够对接其余的一些变动系统。

中间是无人值守的核心系统,根据收集到的分析任务,采集对应的数据,进行分析检测。

最下面一层是离线分析层,主要用来作一些算法的训练、回放验证等,后面再具体介绍。

clipboard.png

大体的业务过程是,用户在发布系统中提交了一个发布计划,这个时候会经过Normandy(诺曼底)这个平台进行发布(海狼是诺曼底平台的一部分,负责发布的执行),海狼开始执行发布单后,无人值守系统就会收到发布单执行的事件,而后开始分析,分析的时候会利用离线算出来的一些特征集,而后和当前的指标进行比较检测,若是有异常,那么会经过海狼的接口进行暂停发布单的操做,用户能够在发布单页面看到对应信息,而后进行一些判断后提交反馈,是有效拦截,仍是误报等。

两个阶段

上述是一个大体的过程,具体实现方面,咱们通过了两个大的版本迭代,下面针对两个版本分别介绍下。

1.0实现

clipboard.png

经过前面的介绍,应该大体了解,无人值守发布就是分析发布过程当中各类指标数据,来判断发布是否有异常,那么具体有哪些指标数据能够用来分析呢?大体总结了下,有如下几类:

首先是业务指标,这个最直接反应当前发布有没有问题,若是影响到了业务,那么基本上就是有问题的。若是业务指标可以覆盖全部的故障场景,那么理论上只要分析业务指标就好了,可是现实每每是不少业务指标的完善都跟不上业务发展的,业务上去了,指标还没上,这是很现实的事情。

其次是一些基础指标,例如机器的内存使用状况,cpu使用率,load状况,磁盘io等,这些指标通常在发布过程当中不太会发生明显的变化,可是一旦发生了明显变化,就可能有问题了。

还有些中间件的指标,阿里内部普遍使用的hsf、tair、metaq等,都有相应的qps、rt、成功率等指标,若是发布后成功率忽然跌的比较明显或者qps跌0等,那么也颇有多是有问题了。

还有一个比较关键的是日志,阿里比较多的应用是java的,咱们会在日志中把一些异常的堆栈信息都打印出来,这些异常信息反映了代码运行过程当中的一个不正常状态,因此是一个很宝贵的指标数据。经过分析这些异常的出现状况、涨幅状况、或者是否出现了一些常见的容易引发故障的异常,例如ClassNotFound等,咱们能够作出足够有用的判断。

指标和算法选取

指标这么多,咱们一开始应该从哪入手呢?

第一个版本的时候,咱们选择了基础监控和日志这两方面入手。缘由比较简单,基础监控的覆盖率够高,有足够多的数据可让咱们分析,而日志根据经验则很是重要。至于业务监控和中间件指标,因为数据方面等一些问题,第一个版本咱们没有去考虑。

那怎么对基础监控和日志的指标进行分析呢?咱们采用的是使用一些简单的规则加上复杂的算法共用的方式,针对一些状况,例如出现了前面提到的危险异常等,采用规则的方式,直接进行拦截,针对异常的涨幅变化等,则采用算法来评判这个涨幅是否在合理范围内。

如何实现

肯定好了指标和分析思路,咱们再看看须要作哪些事情。首先要作的是数据采集,咱们面临的问题是须要采集哪些数据,怎么尽快地采集这些数据。其次是对数据进行处理,原始的数据中会有一些干扰的数据,干扰的来源多是多方面的,多是数据采集系统自己的问题,也多是与业务自身的特色有关,须要把这些干扰的数据可以剔除掉。而后就是针对采集和处理后的这些数据,制定什么样的规则,使用什么样的算法,来对它们进行分析,尽量准确的判断出发布后的数据是否有问题。

数据如何采集

首先咱们来看看数据怎么采集?

采集以前,先明确检测的大体思路:发布前和发布后的指标进行对比,已发布和未发布的机器进行对比。因此,咱们要采集的是时间序列的数据,也就是每一个时间点某个指标是什么样的一个数据,例如某个时间点,系统的load是多少,某个时间点,某类异常出现了多少次等。

具体要采集哪些指标,上面已经明确了,只要把这些指标再作一个分析,把最重要最能反映故障状况的一些指标挑选出来,采集过来就行。

而从哪些机器上采集指标呢?前面提到,咱们检测思路中有一条是已发布和未发布的机器进行对比,因此咱们为每一个应用设置了两组机器,一个是发布组,一个是参照组,只采集这两组机器的数据,而不是全部机器的数据都采集。至于采集时间,也不用采集全部数据,只要采集发布先后一段时间内的数据就能够。

采集到数据之后,接下来就须要对数据进行一些处理,除了前面提到的一些干扰数据剔除外,咱们还须要进行一些维度的聚合,由于拿到的是一些单机数据,因此须要针对已发布未发布等一些维度进行数据聚合合并,最终生成了能够分析的数据。

数据分析方法

数据分析的方法,咱们采用的是改进型的funnel检测模型,它有这些优势:能够知足针对不一样的指标,采用不一样的算法的需求,不一样的指标有各自的特色,使用同一个算法显然不大合适;其次它的计算须要的资源少,同时检测的速度又够快,还支持不少指标一块儿分析。

clipboard.png

经过上述这些工做,咱们大体就把一个检测系统创建run起来了,这第一个版本在准确率方面表现不是很好,离线跑的时候可以有30%、40%,可是线上实际跑的时候只有10%上下的准确率,因此咱们须要去提高准确率,那怎么提高呢?

答案是不断的分析误报和漏报数据,而后对算法作一些微调。不停的微调算法又带来了一个新的问题,针对这些误报的数据,可能新的算法不会报出来了,可是以前的那些没报的数据呢,用新的算法会不会又报出来了?以前那些报出来的有效拦截,会不会新的算法中就不报出来了?

因而咱们又搭建了以前产品架构中提到的离线回放系统,用来对算法进行回放验证,从以前的误报、有效拦截、未拦截等数据中抽取部分数据,每次算法调整后,经过回放系统对这些数据从新进行检测分析,看看准确率和召回率是怎么变化的,误报的是否还在误报,有效拦截的是否漏报了等等。

无人值守回放系统

clipboard.png

整个无人值守回放系统大体过程以下:录制模块会将线上检测过的发布单的相关数据录制到回放db,而后须要回放的时候,经过回放触发接口,触发无人值守进行检测,检测时候会调用回放系统提供的指标mock接口,从回放db获取数据,而不是从实际的数据源获取数据,将回放检测的结果进行保存,产出回放结果报表。

算法的困境

经过无人值守回放系统,咱们创建了可靠的算法验证机制,经过不断的微调算法来提高召回率和准确率。可是,仍是遇到了一些问题。

首先是须要不断的去分析检测数据,而后调整算法,这个过程是至关耗费精力的,而且不必定可以有相应的回报。还有很重要的一点是,在实践过程当中,咱们发现一些明显的误报信息在重复的误报。

因此咱们须要去探索一个可以解决这些问题的方案。因而,第二个版本,咱们就采用了基于机器学习的方式在原来的基础上作了一些改进。

机器学习的大概过程

clipboard.png

首先会有一个离线学习的过程,经过一些历史的发布单的指标数据和拦截数据,以及用户反馈的一些数据,计算出来应用发布时候的一个特征库,发布的时候,会首先采用一些算法来检测出可疑指标,而后对可疑指标和特征库进行比较,若是发现这个可疑指标落在正常的特征库里,那么忽略掉,不然,就认为发布出现了异常进行拦截,拦截完成后,会根据发布单最终的结果和用户的反馈行为将此次拦截是否有效等数据保存起来,做为下次离线计算的一个输入数据。

三大要素

机器学习也面临几个问题须要去解决,首先是去学习什么样的数据,其次是要经过什么样的方法去学习产出什么样的结果,还有一个就是怎么样把这个学习的结果用到后面的发布检测中去。

样本

咱们首先看下样本问题,就是学什么数据。咱们有的数据大体有这些:发布单数据、发布过程当中的指标数据、拦截是否有效的数据、用户反馈的一些数据。

这些数据看起来不少,天天的发布单有好几万,每一个发布单又有大量的指标数据,可是实际上,每一个应用的特征都是不同的,因此学习的时候必定是基于应用的维度去学习的,而每一个应用的发布数据就不多了,如何从这很少的数据去计算应用的发布特征呢?

计算的思路也有两个,一个是算异常的,比较天然的想法,找出异常的特征,下次若是匹配了异常特征,那么就能够判断发布有问题,一个是算正常的,而应用维度异常的发布每每远少于正常发布,甚至可能都历来没有过异常发布,因此基于异常的维度去计算,也不大靠谱,相对比较靠谱点的,只能是经过正常的发布单数据去计算出应用发布的正常发布特征。

样本中的一个挑战是如何来判断一个发布真正是有问题的,咱们采起的是发布单行为和用户反馈相结合的方式,若是发布单被回滚了,那么就认为是异常的,若是用户反馈说有异常,那么也认为是异常的。

关键和不靠谱是用来描述用户反馈数据的两个特色的,关键是指用户反馈数据很是重要,是最可以帮助咱们去了解应用的各个指标对异常检测是否有帮助的,可是用户反馈数据又具备主观性,发布过程当中出现了某个异常,A开发同窗可能会反馈认为没有问题,而B同窗比较谨慎可能就会反馈认为确实是有问题,如何去平衡这两个特色也是比较棘手的。

clipboard.png

这个就是刚才提到的用户反馈数据,经过这个反馈数据,咱们能够明确的知道某个指标虽然异常了,可是对这个应用来讲,多是彻底没有用的,根本不须要做为检测的依据,那么下次检测的时候就能够忽略掉该指标。

这个反馈数据的采集看似很容易,可是据我所知,在很多公司里,采集这个数据阻力都是比较大的,开发同窗不肯意去填写反馈这些信息,比较幸运的是,咱们经过一系列方式优化,尽量地减小这个反馈对开发的干扰,把这个反馈给强制开启来了,采集到的数据对咱们的帮助确实至关大。

算法

样本数据有了,接下来就要根据样本数据计算出应用的发布特征了,咱们采用的是简单的分类的方法,最初的想法是分红正常、异常、未分类三大类,正常比较好理解,异常是指每次出现都会致使故障的,未分类则是一些新增的或者以前出现过没有变化的一些指标,后面考虑到上面说的异常样本很是小的问题,就把这三类统一成一类了,就是只计算应用发布时候各个指标的一个正常阈值,若是下次发布的时候,指标的值超过了这个阈值,那么可能就是有问题。

具体学习的过程比较简单,总结起来一句话就是:找到正常发布单中指标的最大值,做为应用的正常指标阈值。具体过程是:首先是发布过程当中若是出现了异常指标,那么会去看此次发布最终是不是有问题的发布(经过发布单的行为是否回滚以及用户的反馈等),若是是正常发布,那么和以前的正常阈值进行比较,若是比以前的正常阈值要小,那么忽略,若是比以前的阈值大,那么就更新正常阈值,而若是此次发布是异常发布,那么理论上应该去判断此次的指标是否比正常阈值小,若是小,那么要更新正常阈值,可是实际上,此次发布的问题可能并不必定是这个指标引发的,并且若是确实是这个指标引发的话,那么以前指标比这个值更大的发布应该也是异常的,考虑到这两点,咱们现阶段采起的是忽略异常发布单的方式,只针对正常的发布单进行阈值计算。

指标使用

正常阈值的使用也比较简单。发布过程当中,若是发现了异常指标,那么会找到该指标对应的正常阈值作比较,若是小于正常阈值,那么忽略掉,若是超过了正常阈值,那么做为可疑指标,在一个窗口期内进行多轮检测,窗口期会根据检测的结果作一些动态调整,若是在窗口期内屡次被断定为可疑指标,而且达到了必定比例,那么最终会被断定为异常指标,对发布进行拦截。

整个机器学习的改进过程大体就是这样,经过这个改进,咱们一方面解决了以前遇到的一些问题,提高了召回率和准确率,尤为是准确率方面有了显著提高。另一方面,也释放了大量精力出来,能够更好的优化这个学习的算法。

详情请阅读原文

相关文章
相关标签/搜索