@gaoxiaoyunwei2017
2021-07-02T12:55:29.000000Z
字数 8409
阅读 925
公众号
作者简介
龚诚,58集团智能运维团队负责人。哈尔滨工业大学计算机应用专业,硕士学历。在百度、新浪微博、58集团有丰富的技术和管理经验,专注于智能运维、服务治理、稳定性建设等相关领域,在保障服务稳定性、服务治理等方面有丰富的经验。
本文想跟大家分享以下几个方面:
上图是整体的业务框架。首先最底层是基础架构,基于基础架构在智能运维有一些实现的先决条件,比如系统要有可观测性、可控性,智能运维的落地实施也需要智能的知识图谱、感知和决策能力。这个后面会详细介绍。
基于智能运维能力可以在上层各个应用场景来更好地解决这些问题,最重要的是需要解决的就是故障发现和处理,如何自动地添加监控?如何发现多维度异常并很好地做出告警?系统如果有根因分析和故障自愈的能力。
第二是关于容量的管理和成本的优化;
第三是服务质量的评估。如何评估系统的质量好还是坏?在技术挖掘方面可以分析在哪些方面做得不好,然后把这些单独提出来让系统朝着更完美的方向去演进。
基础架构层面。首先在基础设施层面有机房、网络、安全设备、负载均衡服务、域名解析,这个不管互联网还是银行、券商都类似。随着近几年运维自动化普及,一套自动化的管控系统平台必不可少;还有近几年兴起的在线部分的云原生化以及离线部分。
基于基础架构层面可以做很多事情,这里有两个需求:可观测性和可控性。
可观测性即 Metrics、Logging、Tracing。Metrics 代表各层监控指标,具体一些数值型指标可以看到曲线数据的变化;Logging 就是系统应用的日志,另外,一些变更操作和操作日至也可以理解 为Logging,它是一些事件;Tracing 就是大规模的微服务系统现在越来越多,为了去发现在庞大的系统和复杂的调用链中到底哪一部分出现问题,故障在多个服务间如何传递的,这需要 Tracing 把各个服务连接起来。
可控性就是对于系统要有一定的控制能力,发现容量不足要扩容;发现出现问题可以故障自愈。对于在线服务来说,容错、限流、降级、熔断和容灾都是必不可少的。
智能运维首先要有知识图谱,在运维自动化阶段只要有一个 CMDB 就可以了,智能运维作为自动化运维的更高阶段,它的基础信息也包含 CMDB,如大家比较熟悉的集群服务、对应的分组、实例、负责人及描述个性化的类别标签;实例对应的机房,使用怎样的资源、资源配置部署信息,这些都是一个基础的 CMDB 必须要有的。
比较高级的就是服务画像,大家可以类比为用户画像,通过对于各个服务监控数据的采集,通过数据挖掘的方法可以得出服务本身的特征,如容量特征、访问量特征、健康度、告警特征等等。
有了服务画像之后便于我们更准确全面地了解系统,让它做个性化的分析和告警;服务调用链是服务之间的调用链和依赖关系,对于全局和服务层面基于调用链去分析故障是非常有价值的。
异常的因果关系。正常来说如果出现了不同的异常发出了不同的告警,多个告警间哪个是因,哪个是果?一般只有资深的运维工程师在脑子中有这样的经验。我们为了让系统能够自动地做这件事情就需要把知识教会给智能运维系统,系统把相关的信息挖掘出来自动存储在数据库中,这称之为运维知识图谱中异常的因果关系。
存储的内容分为:
不同监控指标之间的影响关系。 例如某个服务的访问上升,CPU、内存、网卡使用率也在上升,到达一定的容量瓶颈后服务的可用性和响应时间会变坏。这就是单个服务多个指标间的因果关系。
同样,一个大规模微服务系统调用链中的服务间有依赖关系,如果底层服务出现异常,依赖它的服务也会出现异常。例如有A、B、C的调用链,C出现问题影响B,B出现问题就会影响A,这是不同服务间的影响关系。
对于我们覆盖监控故障的发现、排查和处理的全流程,需要这样的能力:
为了减少研发人员和运维人员的工作负担,自动添加好监控,自动维护告警阈值,实现多类型指标的异常监测。
当发现异常之后做好告警收敛、告警合并、告警治理。没有问题不发出告警,有问题准确发出告警,并且包含相关的信息协助我们定位。通过故障根源原因分析多个服务之间和单服务内的因果关系。一旦系统能自动定位故障原因就能做故障自愈。
服务变更后的自动检查、日常的自动巡检,对于一些比较简单容易执行的重复的可以设置故障资源策略来自动执行。最后也可以有服务变更,因为日常的部署变更操作也是比较频繁的,当服务变更之后系统是否有出现异常,这也可以通过智能运维来解决。通过看相关指标是否有变化从而来确定这次变更是成功还是失败,如果失败可以快速回稳进行止损。这些关系可以用到日常的巡检当中用于一些变更导致的问题。
服务质量的评估,对于一些重点业务线进行评估,在多个业务线进行横向比较从而发现是否哪一部分出现了问题。最后是自动挖掘和分析技术风险,把问题主动暴露出来,相关的技术人员一块努力把它解决掉,从而让系统向着完美的方向去解决。
这是稳定性建设领域的几个场景:
第一,关于故障的发现和处理。自动采集数据,自动添加监控,多维度异常检测,做好告警收敛和合并,更高级阶段做到故障根因分析和故障自愈;
第二,容量和成本管理方面。提升资源使用率,拆分各个业务线的成本来降低其成本;二是通过构建容量模型实现容量的预估和规划,提前做好扩容。当然如果出现一些紧急流量可以使用模型和算法来实时扩容。
第三,服务质量评估。运维最关注的质量、成本和效率。质量层面抽象成为最关键的两个指标:可用性和响应时间。成本方面有服务器、云平台、云数据库、云存储及网络带宽、机房间专线带宽,通过刚才的方式进行细分来提升资源使用率或者降低成本。
效率部分,一方面可以评估研发效率:项目代码量、曲线率、测试效率、测试轮数、上线次数以及回滚率;对于运维人员来说,相关的故障处理效率,从故障发现时间、响应时间及解决时长,这些都可以定量评估的。
第四,技术风险发现。可以通过调用链分析架构的不合理、服务不稳定、性能较差和容量不足等问题,从而有针对性的进行优化。
智能监控的全流程覆盖,有六大方面互相依赖:自动采集数据。自动采集数据之后添加监控策略,基于数据和监控策略可以做到多维度异常检测,触发异常做告警,告警之前做告警的收敛和合并,减少告警数量来提升信息含量,为我们排查故障提供更多的信息。
系统如果有智能运维的大脑思考能力,基于服务调用链和智能运维图谱来分析根源和原因就实现了根因分析。根据应急方案和预设的故障自愈策略可以自动解决一些故障。
故障的发现、分析和处理,这是我们运维非常关注的一方面,如何覆盖故障发现和解决的全流程。第二方面就是服务治理,服务治理就是发现服务当中有哪些不完善的点,再去做好评估,做好故障的预警来推动技术人员进行优化。
如何做到高效监控全覆盖呢?无非刚才提到两点:自动采集数据和自动添加监控。其实大家可以理解,数据接入监控有很多种方式,但是想把所有的监控数据想采集全其实是比较困难的,这里可以介绍一些方法论和实践的经验。
对于服务器和容器内部的基础监控,对于所有的服务器和容器来说都需要采集,可以固定把这部分的采集能力实现在 Agent 内部,代码里写清楚有哪些指标。
对于不同的类型服务可以抽象成大类型,针对大类型实行特定的采集方式,从而一类一类来解决问题,最终把大部分类型的数据采集任务都完成。比如说想采集面向用户提供 HTTP 服务的外部服务监控数据怎么采集呢?所有的业务数据和业务流量都是经过 Nginx,通过 Nginx 实时传输和分析数据,可以得到 Nginx 的外部服务,各种 HTTP 代码的响应时间,根据流式计算得到每个业务群的健康程度。
同样,如果后端有很多提供数据的服务,可以用公司内部的基础框架和服务治理的相关系统进行自动采集,这样这一类型的数据也采集到了。对于存储类型的服务,MySQL、Redis、MongoDB 等等。
近几年使用的云相关的服务,Kubernetes、Nginx、DNS 可以通过Prometheus来采集。让 Agent 提供多维度接入的方式,把调用函数介入我们的系统就可以了。
这是如何实现自动化地去添加我们的监控策略。基本上每个公司都有几千个或者几万个微服务。这么多微服务如果完全依赖于人去添加监控,首先工作量非常大,另外受限于大家的精力和经验相关,所加的监控不是那么完整,常常出现故障之后再去补充。
而且随着变更,变更非常频繁导致监控的不是那么完善,唯有通过自动化和智能化的方式才能有效保证监控策略的添加的完整。由于每个集群和每个服务的内部实例个数比较多,所以我们都使用这样一个监控的模型,那对于集群内部有哪些IP、服务器或者容器,这个列表是与集群关联的。这个集群上的服务要监控哪些策略是跟监控模板关联的,哪些人对于这个告警和异常感兴趣也是跟集群关联的。
三者主要信息都是跟集群关联,这三者任何一个发生变化都可以独立变化,最终我们发现异常计算和告警策略的时候和跟集群做联动,联动计算最终下发到后端服务做异常检测。这样的方式是模型比较简单,相关的操作由系统自动完成,让我们用户在管理时是比较简单的。
这是多类型指标的一个异常检测,比较简单的像CPU这种,如果大于某个值告警就可以了;第二个类型是可调整的静态阈值,举了一个响应时间,初期的响应时间比较低,随着服务变更之后响应时间变高,如果那时没有技术人员去修改阈值,系统会自动计算最近一段时间内数值的均值、方差和上下四分位数,通过根据 Tukey's Test 重新生成阈值。简单理解,如果后面的数据变大之后会逐渐把阈值拉高,这样逐渐拉高阈值,使得当前的值不是异常值,不会实现告警,使得系统自动维护这个阈值。
对于PV、UV是跟用户访问的流量低峰高峰来生成,很难用静态阈值来判断异常,我们是用机器模型的方式,用回归模型的方式来解决预测的问题;用分类的方式来解决异常监测的问题。
在告警的治理和告警的合并方面,目标也是要降低告警的数量,并且提升告警信息的质量。这里面有三点可以做:
第一,设置合适的告警策略,减少告警的数量,减少对人的干扰。
在智能告警合并这方面可以把同类的告警合并起来提供一个概况信息,同一个集群如果CPU同时上升,不需要发几十条告警,只需要发一条就可以了。另外我们提供了更直观的告警,通过微信展示更多维度的信息。
告警收敛策略比较简单,首先做一个告警的分级,最低一级是邮件,依次升高有微信、短信和语音。连续几次异常则告警,避免出现一些噪点导致误报;二是在几分钟时间段内有几次异常告警则会发现服务的数量;三是告警间隔设置5分钟,最多告警N次,由于一些特殊的原因运维人员没有及时处理或者忘掉,可以30分钟后做一次升级,以前是邮件的方式,现在可以用短信和语音的方式,总之更清晰更直观通知到相关的人员而避免这个事件被漏掉。最后告警升级后,如果没有响应可以发送给Leader。
告警合并首先要选择合适的告警窗口,为了兼顾合并的时效性和效果,一般来说选择1分钟的维度,把1分钟的数据进行合并。通过合并取得很多收益,尤其是告警的数量比较少,减少我们的干扰。合并的策略其实很基础的一点:同一个人的告警进行合并,不要把其他人的告警合并进来。不同的告警状态代表不同的语义含义,不要合在一起。
不同告警级别(语音、短信、微信)属于不同的重要程度。基于以上三个维度可以把1分钟之内所收到的告警进行划分,在此基础上针对所有的告警按照算法进行合并。
合并的维度大家比较熟悉,我这里举了几个例子,一是集群、IP、网段和异常种类,物理机和虚拟机也存在一些关系,可以按照常见的维度去合并。
这是自创的告警合并数算法,通过前面的规则基本上把同一个人、同一种类型和同一种方式的告警拆分开,生成了这个树的根节点。通过基尼值评估的方式,算法把它从树的根节点细分成一颗颗子节点,细化到叶子节点的时候把大集合划分成为小集合。
这是我们合并的效果,这是用微信告警,一个叫 monitor_all
集群有20多台服务器同时宕机,正常情况下要发20条告警,这种情况下只需要发1条。点进去看到概况信息,它直接告诉你某一个集群当前有20台机器告警,而且告诉当前宕机数量占总数量的比例。如果你想看详情可以点击列表。
我们不仅仅把多条告警合到一块,直接告诉你合成多少条。我们提供了一个更好的效果,不但告诉你是按照哪些维度合并的,表里面的内侧有合并的维度,树可以从树节点、根节点到叶子节点,经过了哪些节点可以按照维度来合并。可以告诉他按多个维度合并之后有多少信息,某个集群有22条宕机告警,异常比例84%,异常22个。更像人和人之间的沟通,一个工程师收到告警全看了一遍,通过人的能力总结出来。
通过告警合并,告警的数量也能急剧减少,减少80%-90%,极大减少干扰。
如何更直观展现告警信息?告警信息里面有一 部分是基础信息:服务名称、实例IP、监控指标、数据标签、异常描述、持续时间、告警条件、告警方式、告警接手人。
二是异常数据视图切入进去,看到近期相关指标的变化,从而判断这是不重要的异常还是严重的故障。
三是系统通过做告警根因分析,可以分析出多服务间影响关系及单个服务内部多指标间影响关系;
四是故障处理。提供故障处理建议,做故障自愈操作。
五是故障信息的展示。不在工作场景,在移动场景,在路上、休假或者晚上休息时,不方便用电脑可以在这里面做简单的操作。比如说我可以认为告警不重要,就可以屏蔽掉;如果觉得告警的策略不合理可以修改,如果觉得其他人也需要告警可以转发或者让他订阅。
讲一下故障的原因分析,其中提到了一些挑战:
第一,传统的方式短时间之内会有大量的告警,系统现在基本上是微服务架构,大量的服务有频繁的系统变更和应用级变更。
第二,频繁的系统和应用变更。排查时要去系统看数据,要去变更里看数据,工作量非常大,漏掉之后系统的排查就比较困难了。
第三,转瞬即逝的故障现场。举一个例子,如果有一台服务器处于假死状态,不清楚哪个进程CPU或者内存使用率过高导致的,一般来说重启就可以了,但是你重启之后故障的现场也消失的,我们通过Agent把相关的信息快照抓取,从而进行保存并分析。
第四,复杂的服务调用关系网。微服务的调用非常复杂,单靠人工排查非常困难。而且光靠人去整理调用链非常困难,一些资深的工程师要画出完整的调用链也非常困难,一个大的业务线涉及到大业务部门之间的互相调用。
第五,依赖人的经验和分析能力。即使把所有的信息给到我们,工程师也需要很强的经验和分析能力,才能够在比较短的时间内分析出问题。这一切决定了人去排查是困难重重。
第六,从系统中获取数据困难。
如果通过系统去中,计算机有强大的算力,并且有丰富运维的知识图谱和知识库。怎么做到呢?人怎么做到呢?人有领域的知识和经验,我们也需要为计算机构建出来这样一个知识图谱,里面要有领域的知识和经验。就像上面提到的CMDB、调用链信息和领域内专家的经验。
另外,系统需要有逻辑分析能力,我们需要为它构建起一个强大的分析能力,能够通过调用链,看看哪些服务出现问题以及故障之间的因果关系自动定位故障的原因,并且能够从所有的监控系统和变更系统当中把数据抓取过来,在时间维度和服务维度对齐之后进行综合分析。
如果一切信息分析出来之后,人怎么快速理解故障的分析结果,所以把信息直观展示非常重要。包括常用的PC端以及移动场景所需要的微信端。
构建知识图谱怎么做,基础的部分CMDB、调用链及运维领域知识。运维领域知识可以跟资深的工程员沟通,让他整理;可以通过挖掘的方式从历史告警和事故中发觉哪些指标有关联,之间的因果关联是怎样的。
服务调用链,基于很多开源技术或Skywalking、公司的内部系统采集到。
知识应用图谱需要对于多维数据进行收集,数据对于智能化系统来说非常重要,人工智能方面非常重要的就是数据,有了数据之后才可以去训练模型,让人工智能才有一些智能,尽可能收集一些比较全的数据对齐相关的数据,这个过程比较持续,把系统逐步打通去快速迭代。
有了基础数据、多平台数据之后进行关联关系的挖掘,最终得到了类似于这样的监控指标。比如说如果我们表示可用性的计算关系,除去500、504的HTTP状态码,如果出现比较多的500状态码,是不是可用性是一定下降的?另外还有刚才举的例子,如果某个服务的访问量上升,它的CPU资源使用率,内存使用率和网卡使用率肯定是上升的,这几个指标上升导致服务的可用性和响应时间变差。相应的数据挖掘出来并记录在知识图谱当中。
前面有了相关的知识和经验,下一步就是为系统构建出分析的能力。那我们先从根因分析的场景出发看我们需要哪些分析能力:
第一,多服务之间的互相调用;
第二,单服务的调用。
另外也会有一些单机的异常,比如说物理机、虚拟机宕机,当物理机宕机之后会影响虚拟机,服务会出现假死或资源不足,机房网络的流量之间有一些异常。
我们使用行为树的控制逻辑,有两种节点:非叶子节点是逻辑节点,叶子节点是行为节点。逻辑节点分析流程考虑到哪些点并去验证;行为节点会拉取相关的数据进行比对和相似度计算,从而确定这个逻辑是否有问题。
这是整体的根因分析框架,左侧接入各种维度的数据;中间部分是根因分析行为树来组织各个节点和逻辑从而验证某个部分是不是有问题,最终生成一个根因分析的结果,用一个比较好的方式可视化展示出来。
这是我们最终的展示效果,这其中也是提供根因分析的文字性描述,通过一句话概况当前发生的情况。另外也会有一些服务的变更记录、异常的相关指标、异常的日志等等,基本上通过一个页面和一个告警就可以看到所有排查故障所需要的信息,所以可以很快发现问题。
故障自愈方面的处理原则:没有把握的预案给一些故障处理建立;有风险的预案,请用户确认后操作;经过验证的预案,直接执行故障自测操作。重要的故障一定要有应急预案库;做好故障处理预案的自动化和正确性验证;三是用故障一演练持续保证预案的正确性。
在容量管理方面也用到了一些资源使用率的评估;容量规划和预算的相关管理。另外在成本优化方面也是把各种类型的成本拆分到各个业务去发现有没有哪些低负载了服务器可以下限,哪些业务线所用的存储资源和网络贷款太多,可以看一下具体优化的方法。
单服务的容量评估和规划。选取近段时间每天的峰值,用峰值预估到底走向哪个趋向。并且用压力测试的方式去计算,在有多大业务量的时候CPU内存各项指标的占用情况,收集到这些信息之后把资源使用率的业务访问量以及当前所用的资源作为一个模型参数,输入到机器模型去训练,最后应用就可以把特征抽取出来反向到模型而得到情况。
通过这样的方式可以预估容量,另外也可以去看到哪些服务会是一个性能瓶颈,我们也是语流一些Buffer的容量,最后得出之内有多少实例。
对于多个服务的微服务架构来说,我们也可以通过全局的链路来进行分析,通过全链路的压测找到瓶颈服务。成本优化刚才就提到了这几点。
其实服务质量评估也是重要的一部分,对于业务负责人来说非常想知道宏观的报告,我负责的业务条线宏观情况;对于工程师来说希望你报告给我一些问题并进行优化。宏观层面围绕质量、成本和效率分别提供一些可用性排名、评估和占用的情况,研发效率和测试部署效率。
微观层面给工程师提供比较细致,业务、服务、接口、函数等维度的可用性和响应时间等等。
技术风险挖掘这一方面,我们也是使用了一些混沌工程相关的方法和全链路压测,提前发现系统当中有哪些异常,发现异常,有针对性地解决异常。类似于平常有一些小考,大家不断改进,等到期末有一次大考来判断一下整体的情况。这里面提到了混沌植入和红蓝对抗。
总结一下稳定性建设领域智能运维怎么应用呢?依托于基础架构和基础设施,具备基础的可观测性和可控能力,借助于人工智能赋能的相关技术,在多个运维的场景可发挥作用。最重要的就是故障的发现、分析和处理,另外就是容量处理、成本优化、服务质量评估和技术风险的挖掘。