基于研究论文《Fault Analysis and Debugging of Microservice Systems: Industrial Survey, Benchmark System, and Empirical Study》(作者:周翔、彭鑫、谢涛、孙军、冀超、李文海、丁丹)形成本文。该论文由复旦大学计算机科学技术学院彭鑫教授领导的智能化软件开发 CodeWisdom 团队与北京大学谢涛教授、新加坡管理大学孙军副教授合作完成,并被评选为软件工程领域的国际旗帜期刊、CCF A 类期刊《IEEE Transactions on Software Engineering》2018 年唯一的最佳论文。该奖项由评选委员会从该期刊 2018 年录用的 109 篇论文中评选而出。此奖项本次是第一次颁发,隶属于 IEEE 计算机学会 2019 年发起资助的最佳论文奖计划。这个计划的目的在于表彰和奖励 IEEE 计算机学会旗下每个期刊杂志在上一年度发表的最佳论文。
论文链接:https://cspengxin.github.io/publications/tse19-msdebugging.pdf
相关研究数据:https://fudanselab.github.io/research/MSFaultEmpiricalStudy
微服务开源项目(TrainTicket):https://github.com/FudanSELab/train-ticket
微服务故障案例实现:https://github.com/FudanSELab/train-ticket-fault-replicate
背景
近年来,越来越多的企业开始采用微服务架构。一个大型的企业级微服务系统通常会包含成百上千的微服务,每个微服务都可以由容器编排系统(例如Kubernetes,即k8s)创建并管理多个实例,整个系统运行在数以万计的计算节点上,并通过大量的服务间调用响应用户的各种请求。
微服务系统的这种天然的复杂性和运行环境的动态性给微服务的故障分析和调试带来了巨大的挑战。开发者定位一个故障根源往往需要理解非常复杂的服务调用链,其中大量都是异步调用,因此微服务系统故障分析与调试经常都非常费时费力。
针对这些问题,我们开展了此次针对微服务故障分析与调试的实践研究。
01
我们首先调研了工业界微服务系统的典型故障案例以及故障分析与调试实践方法。
01
然后,我们根据所调研的工业界微服务系统的特点开发了一个中等规模的开源微服务基准系统TrainTicket,并在该系统上重现了22个典型的微服务故障案例。
01
在此基础上,我们提出了多种基于日志分析与可视化的微服务系统故障定位策略,构建了相应的分析工具,并在所重现的故障案例基础上进行了实践对比和分析。
1
微服务故障案例调研
我们邀请了16位具有微服务技术背景的资深工程师参与调研,整理了22个典型故障案例,涉及13种不同的微服务系统,相关系统规模从50个微服务到1000个微服务不等。图1展示了22个典型的工业故障的详细描述,对于每种情况,该表列出了故障的报告者、故障的症状、故障的根源以及用于定位故障根源的时间。
图1. 22个典型的微服务故障案例
根据这些故障的症状(功能性或非功能性)和故障的根源(内部逻辑、服务交互、系统配置),我们把这些故障分为了6类,如图2所示。
功能性故障
主要包括那些由于运行产生的不正确的结果而导致系统服务失效的情况
非功能性故障
主要包括那些会影响服务质量的情况,如性能和可靠性。
内部逻辑故障
主要表示那些由于单个微服务的内部实现错误导致的故障
服务交互故障
主要表示那些由于多个微服务之间的交互实现不合理导致的故障
系统配置故障
主要表示那些运行时基础设施的配置不当导致的故障。
图2. 微服务故障案例分类
2
微服务故障分析与调试实践调研
与此同时,我们也调研了工业界的故障分析与调试实践,归纳了如下三个层次的实践方法,如图3所示。
01
基本日志分析(Basic Log Analysis):在原始日志上进行分析,在这个级别上日志通常是零散的,开发人员需要在各个不同的节点上分析系统生成的各种原始日志以定位故障;
02
可视化日志分析(Visual Log Analysis):在日志数据上进行可视化分析,在这个级别上日志往往是结构化并且可视化的,结合相关统计图表进行故障定位;
03
可视化轨迹分析(Visual Trace Analysis):针对微服务执行轨迹(trace)进行可视化分析,在这个级别上开发人员可以结合系统的执行轨迹的信息(如微服务的服务之间的调用链的信息)进行故障定位。
图3. 故障分析与调试实践方法的三个层次
针对以上这6大类故障,以及三个故障分析与调试实践方法层次,我们进一步分析了故障诊断过程中普遍存在的7个故障诊断步骤。如图4所示,我们针对22个典型故障,分类并整理了各种不同故障类别,在不同的故障诊断成熟度级别下,在7个故障诊断步骤下所分别消耗的时间。
这7个步骤分别是初始理解(IU)、环境搭建(ES)、故障重现(FR)、故障识别(FI)、故障范围界定(FS)、故障定位(FL)和故障修复(FF)。
我们根据这些汇总的信息,分析了不同故障类别下,不同成熟度对不同的故障诊断步骤所带来的正面和反面的影响,及其背后蕴含的规律。
图4. 微服务故障案例分析与调试实践步骤
3
微服务开源基准系统
为了能进一步研究工业界故障案例及其相关故障诊断实践,我们开发了一个开源微服务基准系统TrainTicket,部署运行在K8s+Istio上,集成了相关监控分析工具(包括ELK、Zipkin等)。
如图5所示,TrainTicket系统提供典型的火车票预定相关功能,如车票查询、车票预订、付款、改签和用户通知等等。它是基于微服务的设计原则设计的,涵盖了不同的服务间的交互模式,如同步调用、异步调用和消息队列。系统包含41个与业务逻辑相关的微服务(不包括数据库和基础设施微服务)。它总共使用了四种编程语言:Java、Python、Node.js和Go。我们在此系统上重现了工业调研中的收集的所有故障案例,以支持我们的后续关于故障诊断的研究。
图5. 微服务基准系统TrainTicket架构
4
微服务故障分析与调试经验研究
为了进一步评估企业现有的微服务故障分析与调试方法的有效性并探索可能的技术改进,我们在微服务基准系统TrainTicket以及所复现的故障案例基础上进一步进行了经验研究。
01
定性分析
02
定量分析
03
改进的微服务系统故障分析方法
我们分别通过定性分析和定量分析来研究三个不同成熟度级别的调试实践的有效性。对于每个故障案例,选择三个开发人员使用不同成熟度级别进行调试。我们观察到,对多数故障,使用更高级别的调试实践(从基本日志分析、可视化日志分析、到可视化轨迹分析)会一定程度的缩短调试的总时间。在这些故障案例中,服务交互故障的调试是从更高级别的调试实践中获益最多的故障调试。
为了更好地支持微服务系统的故障分析和调试,我们在现有的分布式调试工具Shiviz(https://bestchai.bitbucket.io/shiviz/)基础上提出了一套改进的微服务系统故障分析方法。Shiviz实现了一套非常友好的基于事件的服务间调用的可视化接口,并且支持很强大的调用链集合搜索功能,以及调用链比较功能,非常适合故障诊断。我们针对该可视化工具实现了相应的日志转化,构建了相应的针对微服务故障的执行轨迹可视化工具用于辅助开发者进行故障诊断。具体思路如图6所示。通过执行轨迹的两两比对(事件节点簇比对)来找出其不同点和相同点,并基于此定位到故障根源。例如,我们先通过比较同一故障的正确和出错调用链之间的差别来找出故障大致的位置,然后比较同一故障的两个出错调用链的相同部分来进一步定位故障根源。
图6. 改进的微服务故障分析方法
图7展示了故障F10的服务级别分析示例,我们通过执行轨迹日志的转换,以控制可视化视图的监控单元(顶部节点)为微服务或微服务状态,然后构建出如图7所示Shiviz的执行轨迹比较视图(左侧为正确执行轨迹,右侧为故障执行轨迹)。对比中看到红框中有两个差异(菱形),差异处即为潜在的故障根源位置。
图7. 故障F10的服务级别的分析示例
图8展示了故障F12的服务级别和服务状态级别的综合分析示例,当我们进行如图8(a)所示的服务级别分析时,我们发现:失败执行轨迹和成功执行轨迹之间没有区别。于是,我们引入微服务状态级分析,通过引入状态变量或表达式来改进执行轨迹的比较。如图8(b)和图8(c)所示,在服务状态级别的分析中,差异之处在于订单服务节点的管理员车票检查区域状态这里,该状态便是潜在的故障根源。
图8. 故障F12的服务级别和服务状态级别的综合分析
示例
基于改进后的执行轨迹可视化工具的可视化策略分析和调试时间分析结果如图9所示。在12个故障案例中,失败的案例有2个(F3和F4),和改进前的现有的工业调试方法的执行轨迹可视化分析结果相同。对于F16,开发人员成功了,但使用的时间比改进前的现有的工业调试方法的执行轨迹可视化分析要长。这三种情况都是环境故障(F3和F4是非功能的,F16是功能性的),这样的结果表明调试这些故障并不能从改进后的执行轨迹分析中受益。
在所有其他9个故障案例中,开发人员的平均调试时间从3.23小时缩短到2.14小时,效率明显提高了。这9个故障案例都是交互故障,对于这些故障,故障定位、初始理解、故障重现是从改进后的分析中获益最大的三个步骤。与改进前的现有的工业调试方法相比,这些步骤所用的时间分别减少了49%、28%和24%
图9. 基于改进的执行轨迹可视化工具的调试策略和调试时间消耗分析
5
分析与展望
我们进行的针对微服务故障定位的实践研究表明:通过适当的跟踪、可视化技术,可以一定程度地帮助开发者调试微服务的各种故障。但是,我们同时也发现,微服务故障定位需要更自动化和更智能的相关工具的支持。
在大规模的工业微服务系统中,微服务的数量通常成百上千,产生的各种运行时事件的数量也经常会达到数万甚至数百万个。这样的庞大的节点和事件数量会使得可视化分析变得几乎不可行。我们建议,可以从如下方面来寻求突破。
首先,可以在可视化这里提供海量事件的缩放能力和节点/事件簇的能力,其中节点/事件簇可以自适应地将相关节点和事件分组在一起,以便于开发者分析和研究。通过这种可视化优化的方式来减少开发者需要检查的节点和事件的数量。
其次,可以将一些传统的故障定位技术引入进来,结合这些技术中故障定位的思路,实时分析微服务系统的执行轨迹数据,以自动化地定位出故障根源的可疑范围。
再次,也可以把海量的历史执行轨迹日志利用起来,采用数据驱动和基于学习的方法进行故障根源的预测。
来源:https://www.cnblogs.com/zgq123456/p/12209832.html