羊麟威,李 静,饶涵宇,高 颖,毛 冬,乔宇杰
(1.南京航空航天大学 计算机科学与技术学院,江苏 南京 211106;2.国网浙江省电力有限公司 信息通信分公司,浙江 杭州 310016;3.国家电网有限公司 信息通信分公司,北京 100761)
随着云计算、移动计算等不同计算方式的出现,微服务架构[1]成为软件服务设计、开发和交付的最新趋势,越来越多的互联网企业采用微服务架构开发、部署分布式应用软件。例如,腾讯的微信系统包含3 000多个微服务模块,运行在20 000多台物理主机上[2]。但微服务体系结构带来便捷开发的同时,由于其复杂的依赖关系以及频繁交付和部署,导致系统面临更多发生故障的潜在威胁[3],系统随时可能出现意想不到的故障,如并发异步错误、运行资源短缺错误等,当某一微服务模块发生故障时,相关模块组件也会因为依赖调用而发生故障,从而导致大规模的微服务级联故障。为了保证微服务的可靠运行和服务质量,开发人员必须快速修复系统故障。
然而,在微服务体系架构中定位故障会遇到以下挑战:(1)复杂的依赖关系。在微服务架构中,微服务的数量通常多达上百或者上千个,并且通常分布在多台服务主机上,服务之间的调用和依赖复杂且动态变化,一个服务的性能下降可能会广泛传播,导致多个服务出现异常。(2)大量的监控指标。大规模服务之间的通信和调用产生了大量的指标,从中分析出微服务发生异常的每个指标阈值是非常耗时的。(3)频繁的微服务更新。为满足用户需求,需要经常更新微服务模块,在更新过程中,旧模块被新服务所替代,服务之间的依赖关系也会随着更新而变化,从而形成一个动态的体系架构。
针对以上问题,该文提出一种基于自编码器的云上微服务故障定位方法:MicroAFL。MicroAFL是一个基于容器微服务非侵入式程序模型,无需对微服务系统本身作任何修改。MicroAFL首先通过编码器检测系统异常,一旦检测到系统异常,MicroAFL通过微服务之间的调用关系构建服务调用关系图,并将微服务的性能状态与系统资源利用率相关联从而计算服务调用关系图中每个节点的异常权重,接着通过加权的PageRank算法对故障微服务进行排序,完成故障自动定位。实验表明,MicroAFL在故障定位精度上优于对比方法。
该文的贡献如下:
(1)提出基于自编码器重构误差的微服务异常检测方法,学习微服务运行状态与响应时间波动的关联关系,实时检测微服务运行状态。
(2)通过解析微服务之间的通信数据,捕获微服务之间的调用关系,从而构造服务调用关系图以模拟故障传播路径,结合自编码器对微服务响应时间的重构误差与系统资源的利用率更新服务调用关系图中节点的异常权重。
(3)基于服务调用关系图中节点的异常权重关系,提出加权的PageRank算法,增强随机游走概率与节点异常程度的关联性。
(4)通过在华为云上的CCE集群中搭建的Sock-shop微服务系统中注入不同类型的故障检测MicroAFL性能,实验结果表明,MicroAFL在故障定位精度上相较对比方法有所提升。
微服务系统在运行过程中某个微服务可能发生网络延迟、系统资源分配不足等问题,进而引起该微服务运行异常,最终导致整个系统异常,无法对外提供正常服务。该文将检测异常微服务和定位引发系统异常的故障微服务的过程称之为故障定位。目前,学术界和工业界已提出许多解决方案来实现分布式系统中的故障定位,主要分为以下三类。
日志是由代码运行过程中输出的非结构化信息,记录了系统运行的完整信息,是故障诊断常见的信息来源。Xu等人[4]通过挖掘不同组件的系统日志来构建每次请求的执行路径,根据执行路径差异诊断故障,该方法往往通常针对特定微服务系统,诊断结果往往依赖于日志质量,因此不具有很好的通用性。Nandi等人[5]从原始日志中挖掘模板,并从挖掘的模板中提取序列特征以形成跨越分布式组件的控制流图,通过标记与运行时日志预期行为的偏差进行故障定位。然而,随着微服务系统复杂性的不断增加,日志规模不断扩大,导致这类方法在分析微服务异常方面的效率较低。
执行轨迹指的是利用Pinpoint[6]等工具准确记录程序执行路径、调用关系等信息,生成类似图结构的链路追踪信息。Gan等人[7]通过收集调用链路数据信息学习服务行为模式,主动检测系统运行过程中出现与正常服务相违背的行为来分析故障原因。Mi等人[8]通过跟踪执行路径来收集信息,通过分析路径上的延迟偏差确定故障根因。陈皓等人[9]通过收集并建模微服务的追踪信息,将未知故障的执行追踪信息与已知故障的执行追踪信息相匹配, 采用字符串编辑距离衡量相似度以诊断可能的故障原因。但是这类方法往往需要将监测代码注入到目标系统以获得准确调用链信息,面对一个由多个开发团队使用不同语言开发的微服务系统而言,在系统中加入监测点的开销成果过高,可用性较低。
通过调用操作系统或应用系统提供的接口可以采集性能指标数据来分析系统性能变化情况,从而诊断故障根因[10]。Lin等人[11]实时收集性能指标数据并与历史数据相结合,将表现异常的微服务模块添加到故障微服务候选集中,并根据异常微服务和性能指标之间的相关性对异常微服务排序。Thalheim等人[12]构建指标缩减框架和指标依赖关系提取器,通过结合指标维度来推断组件之间的依赖关系进行根因定位。Gulenko等人[13]通过收集不同微服务的性能指标数据构建对应向量,利用聚类算法训练对应微服务性能指标正常特征空间。在实时监测过程中,检查对应性能指标数据构成的向量是否处于正常特征空间来检测微服务是否发生性能故障。Liu等人[14]通过跟踪固定监测数据分析异常微服务,接着通过拓扑图的传播方向分析异常传播链,异常传播链末端的微服务被视为可能的故障根因。时间窗口中的服务依赖关系构建拓扑图,结合历史监测数据分析异常微服务,接着通过拓扑图的传播方向分析异常传播链,异常传播链末端的微服务被视为可能的故障根因。
该文提出一种云上微服务故障自动定位方法,其总体框架如图1所示,主要包括3个模块。数据收集模块负责收集应用程序指标和系统级别指标数据,其中应用程序指标用于检测应用性能问题,系统级别指标用于后续服务调用关系图中节点权重更新。异常检测模块通过自编码器对应用程序指标数据进行编码重构,检测微服务模块是否发生异常。一旦检测到系统异常,故障定位模块通过解析微服务之间的调用关系构造服务调用关系图以分析异常传播路径,利用系统资源利用率与微服务性能的相关性计算服务调用关系图中每个微服务节点的异常权重,最终利用改进的加权PageRank算法定位故障根因微服务模块。
图1 MicroAFL总体框架
微服务系统运行监测是异常检测及故障诊断的基础,MicroAFL作为一个非侵入式故障定位方法,无需对微服务系统进行代码注入便可实时监测并收集微服务系统运行指标数据。该文实时监测的指标主要分为物理资源利用率指标和微服务之间调用的响应时间指标。
(1)
(2)
(3)
一旦检测到系统异常,MicroAFL开始定位引发异常的故障微服务。针对微服务系统复杂的依赖调用关系,通过构建服务调用关系图可以有效地展示服务之间的依赖关系,从而刻画故障在微服务之间的传播途径。构建服务调用关系图的步骤如下:首先,MicroAFL将微服务系统中的微服务集合记为V={v1,v2,…,vn},其中n表示微服务个数。对于任意vi∈V,映射生成图节点si,最终得到图节点集合S={s1,s2,…,sn};然后,通过解析各个微服务之间的通信数据来捕捉微服务之间的调用关系,若微服务vi向微服务vj发送服务请求,则构造一条从si指向sj的有向边eij,构成边集合E={eij},1≤i,j≤n,相同服务请求只会构造一条有向边;接着,将微服务模块ve的响应时间监测指标的重构误差作为节点se的初始异常权重f(se)。遍历计算每个微服务模块的异常初始权重,得到节点异常权重集合F={f(se)},se∈S;最终,得到服务调用关系图G(S,E,F)。
以服务调用关系图G(S,E,F)为基础,根据服务调用关系图中相邻节点间异常权重关系[15]自动更新每个节点的异常权重[16]。对于任意节点se∈S,将包含指向节点se的有向边的相邻节点构成集合AN(se),将包含指向5AN(se)中任一节点的有向边的相邻的节点构成集合NAN(se)。例如图2中的节点s3,AN(s3)={s1,s5,s6},NAN(s3)={s2,s4,s8,s9}。
图2 AAN和NHAN集合示例
接着,计算AN(se)的平均异常权重aScore(se):
(4)
其中,f(si)表示节点si的异常权重, inDegree(se)表示节点se的入度。计算AN(se)的平均异常权重cScore(se):
(5)
其中,aScore(se)反映了AN(se)整体上的异常程度。cScore(se)表示NAN(se)整体上的异常程度。结合aScore(se)和cScore(se)的特征计算节点se的异常权重acScore(se):
acScore(se)=aScore(se)-cScore(se)
(6)
(7)
遍历计算每个微服务节点的异常权重完成服务调用关系图中所有节点异常权重更新。接着采用PageRank算法[17]在服务调用关系图G(S,E,F)中“随机游走”,进一步对每个微服务模块作为故障根因微服务的概率大小进行排序[18]。针对微服务故障定位场景,该文提出一种改进的加权PageRank算法,利用节点异常权重与相连节点异常权重的关系计算游走概率,提升定位故障根因定位准确性。加权PageRank算法随机游走策略是基于每个节点访问其他节点的概率,因此首先需要定义服务调用关系图节点转移概率矩阵U:
(8)
其中,uij代表从节点sj随机游走至节点si的概率。节点异常权值的大小与游走概率相关[19],计算从节点sj随机游走至节点si的概率uij:
(9)
其中,sj→si表示存在从节点sj指向节点si的一条有向边,linkOut(sj)表示节点sj指向的节点的异常权重和。对于任意节点se∈S,e={1,2,…,n},初始化PR分数为PR0(se)=1/n,将所有节点的PR分数表示为向量R0:
R0=(PR0(s1),PR0(s2),…,PR0(sn))T
(10)
在每轮随机游走过程中,迭代更新每个节点的PR分数:
Rm=dU·Rn-1+(1-d)R0
(11)
其中,Rm表示第m轮迭代后所有节点的PR分数向量,U∈Rn×n表示随机游走概率矩阵,d∈(0,1)表示索尼系数,通常d=0.85[19]。经不断迭代更新,每个节点的PR分数会趋于收敛,此时节点PR分数越高,所对应的微服务模块是故障根因的可能性越大,最终根据节点PR分数从高到低的顺序输出故障根因微服务排名列表。
3.1.1 实验环境搭建
搭建的实验环境框架如图3所示。将Sock-shop通过Docker部署在华为云CCE集群中,每个Pod副本最大容量设置为3,Istio作为服务代理与每个容器共同部署在相同Pod中,通过编写locust脚本模拟用户对Sock-shop的接口发起请求,利用第三方工具对Sock-shop注入不同类型的故障来模拟微服务系统出现不同的故障,利用prometheus(普罗米修斯)收集每个微服务相应监测指标。
图3 实验环境框架
搭建实验环境的主要软硬件配置信息如表1所示。
表1 实验环境搭建使用的硬件和软件配置信息
3.1.2 实验对象
Sock-Shop是一款基于Springboot开发的模拟销售袜子的电子商务网站微服务应用程序,是广泛使用的微服务基准应用,微服务之间的通信以HTTP通信为主,并使用RESTful的接口设计风格。每个微服务都可独立开发、部署和扩展。
3.1.3 模拟访问
该文使用分布式开源工具Locust根据不同微服务接口请求规则编写对应Locust脚本,并发生成多个线程执行对不同微服务的请求,模拟用户访问Sock-shop系统从而使得各个微服务模块之间正常通信与调用请求,考虑到不同微服务模块被访问的频率存在差异,如表2所示,对不同微服务模块配置了不同的请求频率。
表2 模块请求频率配置
3.1.4 故障注入
为了模拟微服务系统在运行过程中遇到的性能故障问题,在Sock-shop中注入了以下三种类型的故障:(1)网络延迟(Latency):使用tc工具造成微服务的网络300 ms延迟,模拟在微服务运行过程中的网络延迟。(2)CPU资源耗尽(CPU Hog):stress-ng是一款占用计算机CPU资源的工具,通过stress-ng占用CPU资源80%,耗尽系统CPU资源,模拟微服务缺少运行所需CPU资源故障。(3)内存泄漏(Memory Leak):使用stress-ng对某个微服务节点持续分配内存,模拟微服务系统因所在服务器内存不足而引发的内存泄漏故障。
为了评估MicroAFL的故障自动定位性能,选取以下方法作为实验性能对比方法:
Random selection(RS):随机选择是运维人员在不了解系统特定领域知识的情况下使用的一种方法,故障修复人员每次都会从未排查的微服务中随机选择一个微服务进行故障诊断,直到定位故障。
MicroRCA:MicroRCA[18]利用聚类算法发现异常微服务,再基于服务依赖图提取异常子图,最终使用随机游走算法进行故障定位。
AAMR:AAMR[16]首先基于实时指标数据构建服务依赖图,并通过计算每个微服务的异常分数自动更新每个微服务的异常权重。最后,应用基于页面的随机游走对根本原因进行进一步排序,即对潜在的故障根因微服务模块按照可能性大小进行排序。
为了量化算法模型的性能,采用评估指标AC@K和MAP衡量故障定位效果[18]。
(12)
MAP量化算法的故障定位平均准确率,其中n是微服务的数量。MAP在异常测试集A上定义为:
(13)
表3展示了注入不同类型故障下,MicroAFL在Sock-shop中不同微服务上的故障定位准确率。从表3中可以看出,MicroAFL在每个微服务上的故障定位平均准确率达到了0.85以上。此外,发现 MicroAFL在Shipping微服务上的故障定位准确率普遍低于其他模块,分析这是由于相比其他模块,Shipping微服务被请求的频率以及访问其他模快的频率较低,使得Shipping微服务的响应时间指标监测序列数据波动变化更小,即使由于Shipping微服务引发系统异常,也不易被判定为故障根因。
表3 MicroAFL在不同模块上的故障定位准确率
为了比较MicroAFL与对比方法在故障定位准确率上的差异,复现了对比方法在本实验收集的故障注入测试用例集上的实验结果。实验结果如图4所示,在注入三种故障以及K取不同值的情况下,MicroAFL的故障定位准确率均高于其他方法,表明MicroAFL在故障定位方面准确率方面确实得到了有效提升。通过分析,故障定位的准确率提升主要归因于构建服务调用关系图时结合了异常检测时的重构误差,重构误差的大小在一定程度上反映了故障的严重程度和持续时间,在服务调用关系图节点权重更新时结合了重构误差所携带的特征。
图4 故障定位准确率对比实验结果
进一步,通过计算故障定位评价指标MAP衡量MicroAFL算法故障定位平均准确率,实验结果如图5所示。从图5中可以看出,MicroAFL算法对网络延迟(Latency)的故障定位平均精度为0.920,对CPU资源短缺(CPU Hog)故障定位的平均精度为0.864,对内存泄漏故障(Memory Leak)定位的平均精度为0.912,优于对比方法,证明了文中方法对于提高故障定位准确率的有效性。
图5 故障定位平均准确率对比结果
该文设计了一种名为MicroAFL的云上微服务故障自动定位方法,用于云环境下微服务系统异常检测和故障定位。MicroAFL通过微服务之间的调用关系构建服务调用关系图以刻画云上具有复杂依赖关系的微服务之间的故障传播路径,进而使用一种基于异常权重加权的PageRank随机游走算法对故障微服务进行排序,完成故障自动定位。但该方法在节点异常权重计算过程中只利用了监测指标信息,特征提取相对单一,在以后的工作中,将在服务调用关系图构建以及节点权重计算过程中,结合日志、调用链等信息进一步分析微服务运行特征,从而研究更细粒度的故障定位。