一种面向微服务应用的失效测试工具及方法转让专利

申请号 : CN201910519309.4

文献号 : CN110262972B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 吴国全陈伟朱家鑫魏峻崔承旭

申请人 : 中国科学院软件研究所

摘要 :

本发明公开了一种面向微服务应用的失效测试工具及方法,根据微服务调用链监控信息,采用约束求解技术,自动生成待测故障注入点,并完成注入和异常检测过程。该方法通过对待测故障注入点的消减,提升了失效测试过程的效率,帮助开发者快速了解应用面临故障时的处理能力。除此之外,本发明针对超时模式、重试模式、熔断模式以及船舱模式等常见的微服务故障处理模式分析应用行为,可以辅助开发者快速理解应用实际的故障恢复行为,减少修复故障恢复缺陷的时间。

权利要求 :

1.一种面向微服务应用的失效测试工具,其特征在于,包括:负载发生器、监控模块、注入求解模块、故障注入模块、异常检测模块和行为分析模块,其中:负载发生器,基于用户设计或者被测应用已有的测试用例集,产生并发的用户请求以模拟真实的用户请求流量,到达的用户请求将被应用处理,并产生响应消息;

监控模块,负责跟踪来自负载发生器的请求,并产生服务调用链;在调用链中,监控模块将记录服务调用接口、服务之间的调用关系、请求到达时间、响应时间、URL以及符合Open Tracing标准的其他元信息;监控模块还负责统计应用的状态信息,包括:上游服务和下游服务之间的吞吐量、平均响应时间信息;此外,在故障注入后,如果调用服务无法处理将产生异常消息,监控模块还将负责跟踪异常消息在调用链中的传播路径;

注入点求解模块,以监控模块产生的服务调用链为输入,构造约束并基于Z3求解器计算故障注入点集合,这些故障注入点将被传送至故障注入模块进行故障注入;

故障注入模块,基于注入求解模块得到的待测故障注入点集合,依次在不同的注入点进行故障注入;每次注入故障后,故障注入模块将通知异常检测模块检测异常;为了模拟常见的运行时故障,该模块拦截并操纵服务间的请求/响应消息,定义了两种基本类型故障:返回错误信息(Error)以及消息延迟(Delay),并基于两种基本类型故障,构造更加复杂的故障类型,包括:崩溃(Crash)、挂起(Hang)、断开连接(Disconnect)、过载(Overload);该模块还负责删除对于注入故障的配置信息,从而达到使应用快速从故障状态中恢复的目的;

异常检测模块,收到故障注入模块的通知后,验证响应时间是否正常、响应内容是否包含错误语义以及响应码是否正常,上述三项对响应消息的约束被称为内置断言;除此之外,用户可基于python脚本表达与具体业务逻辑相关的断言内容,被称为用户断言,内置断言与用户断言验证失败,则异常检测模块认为注入的故障导致应用执行发生异常,将通知行为分析模块进行异常行为分析;

故障注入点解集优化模块:根据监控模块监测到的故障传播路径以及异常检测模块的检测结果,分别设计基于故障传播路径剪枝和基于有效注入点剪枝的故障注入点消减策略,优化故障注入点集合;基于故障传播路径剪枝的消减策略通过监控模块得到服务调用链中不能处理该注入故障的服务调用集合,对故障注入点集合进行消减;基于有效注入点剪枝的消减策略通过异常检测模块确定注入故障否导致用户响应消息异常;如果发生异常,则对故障注入点集合进行消减;

行为分析模块,接受到异常检测模块的通知后,负责针对应用发生异常后,应用的故障处理行为进行分析,辅助测试人员理解应用的故障处理逻辑,加速缺陷修复过程, 该模块包括四个步骤:针对超时模式进行分析、针对重试模式进行分析、针对熔断模式进行分析、针对船舱模式进行分析;超时模式分析指行为行为分析模块将指出上下游服务之间的超时阈值;熔断模式分析指行为分析模块指出调用链中存在熔断的服务调用位置;船舱模式分析指行为分析模块指出调用链中共享上游服务连接池的下游服务集合;重试模式指行为分析模块指出上游服务对下游服务中接口的重试次数。

2.根据权利要求1所述的面向微服务应用的失效测试工具,其特征在于:所述的负载发生器的实现如下:(1)读取来自用户的负载发生脚本;

(2)根据负载发生脚本中的测试用例按照比例生成负载,为了模拟线上测试环境中的用户流量,负载发生器将随机决定生成的负载是否是测试流量,测试流量将具有正常流量不具备的特定HTTP请求头;在故障注入模块和监控模块中,将只对这些HTTP请求头造成影响;

(3)构造测试脚本,作为负载发生工具的输入,产生并发的用户请求,经过读取脚本、插入请求头步骤后,交由负载发生工具产生真正的请求负载。

3.根据权利要求1所述的面向微服务应用的失效测试工具,其特征在于:所述的注入点求解模块的实现如下:(1)根据调用链信息,将每个服务调用抽象表示为布尔型变量,其值表示是否在该调用过程注入故障,若值为“true”表示对该服务调用注入故障,值为“false”表示对该服务调用不注入故障;

(2)对于同一个请求可能存在多个不同的服务调用链,为了得到最小的故障注入点集合,将不同服务调用链对应的布尔表达式进行合取构造约束条件;

(3)利用Z3求解器,注入求解模块每次求解一个最简解,并将该解加入约束条件对约束进一步进行限制,最终得到所有的故障注入点集合,并交由故障注入模块进行故障注入。

4.根据权利要求1所述的面向微服务应用的失效测试工具,其特征在于:所述监控模块的实现如下:(1)对于负载发生器产生的并发用户请求,监控模块采用分布式追踪工具Jaeger 收集用户请求产生的调用链信息,包括:服务调用接口、服务之间的调用关系、请求到达时间、响应时间、URL以及符合Open Tracing标准的其他元信息;使用监控信息统计工具Prometheus插件,统计应用的状态信息,包括上游服务和下游服务之间的吞吐量、平均响应时间信息;

服务调用链信息将传入注入点求解模块计算故障注入点集合,监控统计信息将传入异常检测模块检测注入的故障是否产生异常;

(2)在注入故障后,监控模块将负责跟踪注入故障在服务调用链中的传播路径,并根据故障传播路径确定调用链上处理该故障的服务调用和无法处理该故障的服务调用,并将相关信息发送给故障注入点解集优化模块。

5.根据权利要求1所述的面向微服务应用的失效测试工具,其特征在于:所述异常检测模块的实现如下:(1)在注入故障后,异常检测模块判断请求的响应时间是否大于5秒,如果大于5秒,则表明应用的故障处理逻辑存在问题,生成报告;如果小于5秒,则进入步骤(2);

(2)异常检测模块基于响应码对响应结果的语义进行判断,如果响应码以非200系列的数字形式存在,则表明应用的故障处理逻辑存在问题;如果结果正常,则进入步骤(3);

(3)异常检测模块利用请求头“Content-Type”识别JSON数据格式,然后针对JSON格式的响应结果,基于字典抽取目标字段,最后通过该字段的值判断请求是否被成功处理;如果结果正常,则进入步骤(4);

(4)异常检测模块根据用户指定的断言内容对注入故障后的应用进行异常检测;如果仍然无法发现异常,则认为应用可以正常处理当前注入的故障。

6.根据权利要求1所述的面向微服务应用的失效测试工具,其特征在于:所述行为分析模块的具体实现如下:(1)对于应用的超时行为,行为分析模块注入20秒延迟故障,然后获取调用链,分析超时的调用过程, 超时调用过程的时长即为超时阈值,生成报告;

(2)对于应用的重试行为,行为分析模块注入响应码为500的故障,然后获取调用链,分析重复的且出错的调用过程,重复次数即为重试次数,生成报告;为了避免正常处理逻辑中存在多次调用过程导致误报的情况,行为分析模块将对比正常情况下的调用次数和分析结果;如果二者相同,则证明业务逻辑决定存在多个相同的调用过程;

(3)对于应用的熔断行为,行为分析模块注入响应码为500的故障,然后获取调用链,对比注入故障前后的调用链,消失的调用过程即为被熔断的调用过程,生成报告;

(4)对于应用的船舱模式,行为分析模块注入20秒延迟故障,增加上游服务到目标服务的连接数量,消耗上游服务的连接资源,检测上游服务到其他下游服务的吞吐量,如果吞吐量明显下降,则表明上游服务缺少资源隔离处理,生成报告。

7.一种面向微服务应用的失效测试方法,其特征在于,步骤如下:

(1)产生并收集调用链

以待测应用为输入,跟踪用户请求并产生服务调用链,然后根据服务调用链的组成对用户请求分类,避免重复测试相似请求,最后输出经过分类的服务调用链;

(2)求解注入位置与解集优化

求解注入位置过程的输入是服务调用链信息,可抽象为图模型,首先基于图构造约束条件,然后基于Z3约束求解器计算满足约束条件的解集,解集对应着故障注入点集合,最后解码并根据历史信息消减故障注入点,输出待测的故障注入位置;

构造约束条件的步骤如下:

a)将调用链中的服务用点表示,调用过程用有向边表示,形成有向图;

b)将单个调用链的图中所有的点用析取符号连接,构成子约束表达式;

c)同一个请求涉及的多个调用链将产生多个子约束表达式,用合取符号连接这些子约束表达式,构成最终的约束表达式;

基于Z3约束求解器计算解集的过程如下:

a)利用Z3求解满足约束表达式的单个最简解;

b)记录最简解,并对求得的最简解构造约束表达式后取反,和原表达式用合取符号连接,得到更新后的约束表达式;

c)若该表达式可满足,则重复步骤(1);否则结束求解过程,得到故障注入点解集合;

所述优化解集过程包含基于故障传播路径剪枝的消减策略和基于有效注入点剪枝的消减策略,具体如下:a)基于故障传播路径剪枝的消减策略收集监控模块得到的服务调用链中无法处理该故障的服务调用,并遍历故障注入点集合,如果集合中的元素包含该服务调用,则将该元素从故障注入点集合中消除;

b)基于有效注入点剪枝的消减策略检查故障注入后异常检测模块是否检测到异常,如果发生异常,则遍历故障点集合,对于集合中的每个元素如果包含该故障注入点,则将该元素从故障注入点集合中删除;

(3)注入与异常检测

执行测试过程首先基于步骤(2)的求得的待测故障注入位置注入故障,然后分别进行内置断言和用户断言的验证,记录无法处理的故障场景并更新测试历史,最后撤销故障;

所述内置断言和用户断言的验证过程如下:

a)检测响应的时间,如果超过5秒,则探测到异常,生成异常报告;否则继续步骤(2);

b)检测响应码,如果是非200系列响应码,则探测到异常,生成异常报告;否则继续步骤(3);

c)判断响应内容是否为JSON格式,如果是JSON格式,根据字典提取含有响应处理结果语义的关键字的内容,如果成功提取,则判断内容是否为“true”,如果是“false”,则探测到异常,生成异常报告;否则继续步骤(4);

d)执行用户指定的python断言脚本,在标准输出流中获取python脚本的执行结果;以JSON格式解析执行结果,并且以接口的url提取该接口的断言执行结果;若提取得到的值为“true”,则说明应用可以正常处理该异常;否则,说明工具探测到异常,生成异常报告;

(4)模式检测

针对应用无法应对的故障场景,从四个角度,即超时模式、重试模式、熔断模式以及船舱模式依次分析故障恢复行为,输出相应的分析结果;

超时模式行为分析实现为:

a)在步骤(3)中发现异常的注入位置注入20s延迟;

b)监控调用链中调用的响应时间,如果响应时间明显大于正常情况下的响应时间,则认为该响应时间为超时阈值;

c)撤销延迟;

重试模式行为分析实现为:

a)在步骤(3)中发现异常的注入位置注入响应码为500的故障;

b)监控调用链的变化, 如果调用链中,上游服务对下游服务的相同接口调用次数和正常情况下不同,则认为该调用为重试行为,调用次数为重试次数;

c)撤销故障;

熔断模式行为分析实现为:

a)在步骤(3)中发现异常的注入位置注入响应码为500的故障;

b)监控调用链的变化, 和正常情况下的调用链相比,调用链中消失的调用过程被熔断,处于最上游的消失的调用过程为熔断位置;

c)撤销故障;

船舱模式行为分析实现为:

a)在步骤(3)中发现异常的注入位置注入20s延迟;

b)监控相关上下游服务之间的吞吐量变化,和正常情况下的吞吐量相比,若上游服务到下游服务之间的吞吐量均大幅降低,则缺失船舱模式;

c)撤销故障。

说明书 :

一种面向微服务应用的失效测试工具及方法

技术领域

[0001] 本发明涉及一种面向微服务应用的失效测试工具及方法,属于互联网以及Web技术领域。

背景技术

[0002] 随着软件规模的持续膨胀和业务需求的不断变化,如何快速部署软件产品、灵活分配开发任务、大幅加速迭代周期,成为Netflix、Google、Amazon等大型公司亟需解决的问题。在此背景下,微服务架构以及相关技术应运而生。Netflix、Amazon、The Guardian、BBC、Twilio等公司已经将微服务架构应用于线上环境。使用微服务架构开发云应用已经成为趋势。微服务架构将单体应用划分为多个专注于单一功能的子模块,通过标准的轻量级协议交互信息并提供服务。每个小型功能模块被称为一个微服务。各个微服务独立开发、部署和管理。新的特性和功能可以增量式添加至目标服务中,便于在生产环境中持续发布。在特定应用场景中,微服务应用每天发布的次数可以达到上百次,获得了极大的灵活性。
[0003] 和中小型应用相比,微服务架构对于大型应用的意义更为明显。但是对于大型应用而言,诸如宕机、火灾等低概率事件在庞大的集群规模以及不稳定的用户流量面前频繁发生。为了提供“一直在线(Always-on)”的用户体验,大型微服务应用通过服务降级、失效转移、超时重试等一系列故障恢复策略对局部服务失效现象进行管控,使核心服务能够正常提供功能,保证了系统的可用性。除此之外,金融领域与军事领域对执行结果的正确性要求格外严格。故障恢复策略的设计与实现使微服务应用以可靠的方式提供服务,避免了大量的经济与人员损失。总而言之,设计并实现正确的故障恢复策略是大型微服务应用保证可用性的重要方式。
[0004] 在实际的设计与开发过程中,故障恢复策略的正确性并非总能得到保证。
[0005] 首先,应用的复杂度由业务逻辑决定,不会由于采用微服务架构而降低。同时每个服务专注于单一功能,服务内部的复杂度降低,最终导致微服务应用中的交互关系变得庞大且复杂。一方面,数量众多的交互关系导致了不正确的实现和配置。另一方面,交互场景由具体的业务决定,具有多样的功能性需求和非功能性需求,即交互关系具有多样性。相关人员由于对业务场景不熟悉或者盲目自信等原因,错误实现或配置重要的故障恢复策略。综上所述,数量众多且具有多样性的交互关系使治理微服务应用变得格外困难。
[0006] 其次,单元测试与集成测试主要测试应用的功能逻辑。一方面,单元测试和集成测试在执行过程中不会有意触发更多故障场景。应用中的众多故障恢复逻辑无法触发,也无法测试。另一方面,即使故障恢复逻辑被触发,单元测试和集成测试不会针对故障恢复行为进行分析,更无法根据故障恢复行为调整测试步骤,不利于暴露“深层”的故障恢复方面的缺陷。综上所述,单元测试与集成测试难以暴露微服务应用在故障恢复方面的缺陷,导致应用在上线后出现宕机、不可用等现象。
[0007] 2018年中,AWS、微软Azure和谷歌云平台都经历了重大的云服务宕机事件。事件持续时间从20分钟到2个小时不等,造成了严重的影响。在特定场景中,存在缺陷的故障恢复策略将导致比没有故障恢复策略更糟糕的结果。2014年至2017年之间,发生了众多故障恢复策略失效的案例。其中Twilio公司由于Redis的恢复策略不当,导致付款后不到账、系统重复扣款等重大经济问题。研究面向微服务应用的失效测试方法,设计并实现一个面向微服务应用的自动化失效测试工具,对于暴露微服务应用在故障恢复方面的缺陷,提高大型微服务应用的可靠性和健壮性具有十分重要的现实意义。
[0008] 为了自动检测微服务应用在故障处理方面的缺陷,目前工业界和学术界已经提出了有很多的方法和工具。Gremlin(Heorhiadi V,Rajagopalan S,Jamjoom H,et al.Gremlin:Systematic resilience testing of microservices[C]//2016IEEE 36th International Conference on Distributed Computing Systems(ICDCS).IEEE,2016:
57-66.)是其中最具代表性的工具之一。Gremlin由IBM的研究人员开发。基于利用网络通讯注入故障的思想,Gremlin提供了三种基本的故障类型:Abort、Delay以及Modify。使用者可以综合三类基本故障,构成复杂的故障场景,从而达到触发复杂故障处理逻辑的目的,提高发现应用在故障恢复方面的缺陷的机会。除去故障注入能力,Gremlin还提供了对故障注入后系统行为的简单验证能力。利用来自使用者的断言脚本,Gremlin可以帮助使用者快速验证对应用的猜想,适用于和使用者频繁交互的测试场景中。Chaosmonkey(Chang M A,Tschaen B,Benson T,et al.Chaos Monkey:Increasing SDN Reliability through Systematic Network Destruction[J].Acm Sigcomm Computer Communication Review,
2015,45(4):371-372.)由Netflix公司开发,通过随机删除指定范围内的节点注册信息,达到模拟节点崩溃情况的目的。经过多年的实践经验,Chaosmonkey已经可以良好地运行于线上环境,具有很强的实用性。
[0009] Gremlin需要人工指定注入内容。这种方式严重依赖人工经验,而且受限于有限的认知能力,对于庞大的故障注入空间的覆盖率很低。Chaosmonkey缺少有效的反馈信息指引注入内容,容易产生重复注入、无效注入等情况,很难触发复杂的故障恢复逻辑,导致隐藏在复杂故障恢复逻辑中的故障处理缺陷无法被发现。除此之外,相关文献(Zhou X,Peng X,Xie T,et al.Fault Analysis and Debugging of Microservice Systems:Industrial Survey,Benchmark System,and Empirical Study[J].IEEE Transactions on Software Engineering,PP(99):1-1)表明理解应用行为并初步推断问题原因是修复缺陷过程中最耗时的步骤。Gremlin和Chaosmonkey都无法对故障恢复行为进行分析,有必要对常见的故障处理模式进行分析,辅助开发人员进行缺陷修复。
[0010] 总之,现有技术可以实现测试过程的自动化执行,然而需要人工指定执行过程的内容,对于故障注入空间的探测效率不高。其次现有技术并未对常见的故障处理模式进行分析,导致开发者发现应用无法处理的故障场景后,需要花费大量时间定位与修复缺陷。

发明内容

[0011] 本发明技术解决问题:克服现有技术的不足,提供一种面向微服务应用的失效测试工具及方法,通过对待测故障注入点的消减,提升了失效测试过程的效率,帮助开发者快速了解应用面临故障时的处理能力;而且可以辅助开发者快速理解应用实际的故障恢复行为,减少修复故障恢复缺陷的时间。
[0012] 本发明技术解决方案:一种面向微服务应用的失效测试工具,包括:负载发生器、监控模块、注入求解模块、故障注入模块、异常检测模块和行为分析模块,其中:
[0013] 负载发生器,基于用户设计或者被测应用已有的测试用例集,产生并发的用户请求以模拟真实的用户请求流量,到达的用户请求将被应用处理,并产生响应消息;
[0014] 监控模块,负责跟踪来自负载发生器的请求,并产生服务调用链;在调用链中,监控模块将记录服务调用接口、服务之间的调用关系、请求到达时间、响应时间、URL以及符合Open Tracing标准的其他元信息;监控模块还负责统计应用的状态信息,包括:上游服务和下游服务之间的吞吐量、平均响应时间信息;此外,在故障注入后,如果调用服务无法处理将产生异常消息,监控模块还将负责跟踪异常消息在调用链中的传播路径;
[0015] 注入点求解模块,以监控模块产生的服务调用链为输入,构造约束并基于Z3求解器计算故障注入点集合,这些故障注入点将被传送至故障注入模块进行故障注入;
[0016] 故障注入模块,基于注入求解模块得到的待测故障注入点集合,依次在不同的注入点进行故障注入;每次注入故障后,故障注入模块将通知异常检测模块检测异常;为了模拟常见的运行时故障,该模块拦截并操纵服务间的请求/响应消息,定义了两种基本类型故障:返回错误信息(Error)以及消息延迟(Delay),并基于两种基本类型故障,构造更加复杂的故障类型,包括:崩溃(Crash)、挂起(Hang)、断开连接(Disconnect)、过载(Overload);该模块还负责删除对于注入故障的配置信息,从而达到使应用快速从故障状态中恢复的目的;
[0017] 异常检测模块,收到故障注入模块的通知后,验证响应时间是否正常、响应内容是否包含错误语义以及响应码是否正常,上述三项对响应消息的约束被称为内置断言;除此之外,用户可基于python脚本表达与具体业务逻辑相关的断言内容,被称为用户断言,内置断言与用户断言验证失败,则异常检测模块认为注入的故障导致应用执行发生异常,将通知行为分析模块进行异常行为分析;
[0018] 故障注入点解集优化模块:根据监控模块监测到的故障传播路径以及异常检测模块的检测结果,分别设计基于故障传播路径剪枝和基于有效注入点剪枝的故障注入点消减策略,优化故障注入点集合;基于故障传播路径剪枝的消减策略通过监控模块得到服务调用链中不能处理该注入故障的服务调用集合,对故障注入点集合进行消减;基于有效注入点剪枝的消减策略通过异常检测模块确定注入故障否导致用户响应消息异常;如果发生异常,则对故障注入点集合进行消减;
[0019] 行为分析模块,接受到异常检测模块的通知后,负责针对应用发生异常后,应用的故障处理行为进行分析,辅助测试人员理解应用的故障处理逻辑,加速缺陷修复过程。该模块包括四个步骤:针对超时模式进行分析、针对重试模式进行分析、针对熔断模式进行分析、针对船舱模式进行分析;超时模式分析指行为行为分析模块将指出上下游服务之间的超时阈值;熔断模式分析指行为分析模块指出调用链中存在熔断的服务调用位置;船舱模式分析指行为分析模块指出调用链中共享上游服务连接池的下游服务集合;重试模式指行为分析模块指出上游服务对下游服务中接口的重试次数。
[0020] 所述的负载发生模块的实现如下:
[0021] (1)读取来自用户的负载发生脚本;
[0022] (2)根据负载发生脚本中的测试用例按照比例生成负载,为了模拟线上测试环境中的用户流量,负载发生器将随机决定生成的负载是否是测试流量,测试流量将具有正常流量不具备的特定HTTP请求头;在故障注入模块和监控模块中,将只对这些HTTP请求头造成影响;
[0023] (3)构造测试脚本,作为负载发生工具的输入,产生并发的用户请求。经过读取脚本、插入请求头步骤后,交由负载发生工具产生真正的请求负载。
[0024] 所述的注入点求解模块的实现如下:
[0025] (1)根据调用链信息,将每个服务调用抽象表示为布尔型变量,其值表示是否在该调用过程注入故障,若值为“true”表示对该服务调用注入故障,值为“false”表示对该服务调用不注入故障;
[0026] (2)对于同一个请求可能存在多个不同的服务调用链,为了得到最小的故障注入点集合,将不同服务调用链对应的布尔表达式进行合取构造约束条件;
[0027] (3)利用Z3求解器,注入求解模块每次求解一个最简解,并将该解加入约束条件对约束进一步进行限制,最终得到所有的故障注入点集合,并交由故障注入模块进行故障注入。
[0028] 所述监控模块的实现如下:
[0029] (1)对于负载发生器产生的并发用户请求,监控模块采用分布式追踪工具Jaeger收集用户请求产生的调用链信息,包括:服务调用接口、服务之间的调用关系、请求到达时间、响应时间、URL以及符合Open Tracing标准的其他元信息;使用监控信息统计工具Prometheus插件,统计应用的状态信息,包括上游服务和下游服务之间的吞吐量、平均响应时间信息;服务调用链信息将传入注入点求解模块计算故障注入点集合,监控统计信息将传入异常检测模块检测注入的故障是否产生异常;
[0030] (2)在注入故障后,监控模块将负责跟踪注入故障在服务调用链中的传播路径,并根据故障传播路径确定调用链上处理该故障的服务调用和无法处理该故障的服务调用,并将相关信息发送给故障注入点解集优化模块。
[0031] 所述异常检测模块的实现如下:
[0032] (1)在注入故障后,异常检测模块判断请求的响应时间是否大于5秒,如果大于5秒,则表明应用的故障处理逻辑存在问题,生成报告;如果小于5秒,则进入步骤(2);
[0033] (2)异常检测模块基于响应码对响应结果的语义进行判断,如果响应码以非200系列的数字形式存在,则表明应用的故障处理逻辑存在问题;如果结果正常,则进入步骤(3)。
[0034] (3)异常检测模块利用请求头“Content-Type”识别JSON数据格式,然后针对JSON格式的响应结果,尝试基于字典抽取目标字段,最后通过该字段的值判断请求是否被成功处理;如果结果正常,则进入步骤(4);
[0035] (4)异常检测模块根据用户指定的断言内容对注入故障后的应用进行异常检测;如果仍然无法发现异常,则认为应用可以正常处理当前注入的故障。
[0036] 所述行为分析模块的具体实现如下:
[0037] (1)对于应用的超时行为,行为分析模块注入Delay(20s)故障,然后获取调用链,分析超时的调用过程。超时调用过程的时长即为超时阈值,生成报告;
[0038] (2)对于应用的重试行为,行为分析模块注入Abort(500)故障,然后获取调用链,分析重复的且出错的调用过程,重复次数即为重试次数,生成报告;为了避免正常处理逻辑中存在多次调用过程导致误报的情况,行为分析模块将对比正常情况下的调用次数和分析结果;如果二者相同,则证明业务逻辑决定存在多个相同的调用过程;
[0039] (3)对于应用的熔断行为,行为分析模块注入Abort(500)故障,然后获取调用链,对比注入故障前后的调用链,消失的调用过程即为被熔断的调用过程,生成报告;
[0040] (4)对于应用的船舱模式,行为分析模块注入Delay(20s)故障,增加上游服务到目标服务的连接数量,消耗上游服务的连接资源,检测上游服务到其他下游服务的吞吐量,如果吞吐量明显下降,则表明上游服务缺少资源隔离处理,生成报告。
[0041] 本发明的一种面向微服务应用的失效测试方法,步骤如下:
[0042] (1)产生并收集调用链
[0043] 以待测应用为输入,跟踪用户请求并产生服务调用链,然后根据服务调用链的组成对用户请求分类,避免重复测试相似请求,最后输出经过分类的服务调用链;
[0044] (2)求解注入位置与解集优化
[0045] 求解注入位置过程的输入是服务调用链信息,可抽象为图模型,首先基于图构造约束条件,然后基于Z3约束求解器计算满足约束条件的解集,解集对应着故障注入点集合,最后解码并根据历史信息消减故障注入点,输出待测的故障注入位置;
[0046] 构造约束条件的步骤如下:
[0047] a)将调用链中的服务用点表示,调用过程用有向边表示,形成有向图;
[0048] b)将单个调用链的图中所有的点用析取符号连接,构成子约束表达式;
[0049] c)同一个请求涉及的多个调用链将产生多个子约束表达式,用合取符号连接这些子约束表达式,构成最终的约束表达式;
[0050] 基于Z3约束求解器计算解集的过程如下:
[0051] a)利用Z3求解满足约束表达式的单个最简解;
[0052] b)记录最简解,并对最简解取反,和约束表达式用合取符号连接,得到更新后的约束表达式;
[0053] c)若该表达式可满足,则重复步骤(1);否则结束求解过程,得到最简解集合;
[0054] 所述优化解集过程包含基于故障传播路径剪枝的消减策略和基于有效注入点剪枝的消减策略,具体如下:
[0055] a)基于故障传播路径剪枝的消减策略收集监控模块得到的服务调用链中无法处理该故障的服务调用,并遍历故障注入点集合,如果集合中的元素包含该服务调用,则将该元素从故障注入点集合中消除;
[0056] b)基于有效注入点剪枝的消减策略检查故障注入后异常检测模块是否检测到异常,如果发生异常,则遍历故障点集合,对于集合中的每个元素如果包含该故障注入点,则将该元素从故障注入点集合中删除;
[0057] (3)注入与异常检测
[0058] 执行测试过程首先基于步骤(2)的求得的待测故障注入位置注入故障,然后分别进行内置断言和用户断言的验证,记录无法处理的故障场景并更新测试历史,最后撤销故障;
[0059] 所述内置断言和用户断言的验证过程如下:
[0060] a)检测响应的时间,如果超过5秒,则探测到异常,生成异常报告;否则继续步骤(2);
[0061] b)检测响应码,如果是非200系列响应码,则探测到异常,生成异常报告;否则继续步骤(3);
[0062] c)判断响应内容是否为JSON格式,如果是JSON格式,根据字典尝试提取含有响应处理结果语义的关键字的内容,如果成功提取,则判断内容是否为“true”,如果是“false”,则探测到异常,生成异常报告;否则继续步骤(4);
[0063] d)执行用户指定的python断言脚本,在标准输出流中获取python脚本的执行结果。以JSON格式解析执行结果,并且以接口的url提取该接口的断言执行结果;若提取得到的值为“true”,则说明应用可以正常处理该异常;否则,说明工具探测到异常,生成异常报告;
[0064] (4)模式检测
[0065] 针对应用无法应对的故障场景,从四个角度,即超时模式、重试模式、熔断模式以及船舱模式依次分析故障恢复行为,输出相应的分析结果;
[0066] 超时模式行为分析实现为:
[0067] a)在步骤(3)中发现异常的注入位置注入20s延迟;
[0068] b)监控调用链中调用的响应时间,如果响应时间明显大于正常情况下的响应时间,则认为该响应时间为超时阈值;
[0069] c)撤销延迟;
[0070] 重试模式行为分析实现为:
[0071] a)在步骤(3)中发现异常的注入位置注入响应码为500的故障;
[0072] b)监控调用链的变化。如果调用链中,上游服务对下游服务的相同接口调用次数和正常情况下不同,则认为该调用为重试行为,调用次数为重试次数;
[0073] c)撤销故障;
[0074] 熔断模式行为分析实现为:
[0075] a)在步骤(3)中发现异常的注入位置注入响应码为500的故障;
[0076] b)监控调用链的变化。和正常情况下的调用链相比,调用链中消失的调用过程被熔断,处于最上游的消失的调用过程为熔断位置;
[0077] c)撤销故障;
[0078] 船舱模式行为分析实现为:
[0079] a)在步骤(3)中发现异常的注入位置注入20s延迟;
[0080] b)监控相关上下游服务之间的吞吐量变化。和正常情况下的吞吐量相比,若上游服务到下游服务之间的吞吐量均大幅降低,则缺失船舱模式;
[0081] c)撤销故障。
[0082] 本发明与现有技术相比的优点在于:
[0083] (1)本发明基于约束求解技术,根据微服务调用链自动生成待测故障注入点,完成注入和异常检测过程,通过对待测故障注入点的消减,提升了失效测试过程的效率,帮助开发者快速了解应用面临故障时的处理能力。
[0084] (2)本发明针对超时模式、重试模式、熔断模式以及船舱模式等常见的微服务故障处理模式分析应用行为,可以辅助开发者快速理解应用实际的故障恢复行为,减少修复故障恢复缺陷的时间。

附图说明

[0085] 图1为本发明系统的组成框图;
[0086] 图2为本发明方法的设计图;
[0087] 图3为测试用例驱动的负载发生过程的实现流程图;
[0088] 图4为故障注入空间探测的实现流程图;
[0089] 图5为构造约束表达式的实现流程图;
[0090] 图6为基于Z3求解约束表达式的实现流程图;
[0091] 图7为故障注入点消减策略1的实现流程图;
[0092] 图8为故障注入点消减的案例图;
[0093] 图9为故障注入点消减策略2的实现流程图;
[0094] 图10为注入故障与异常检测的实现流程图。
[0095] 图11为超时模式检测的实现流程图。

具体实施方式

[0096] 在阐述本发明之前,对相关的术语等进行一下说明。
[0097] 故障注入点(Injection Point,IP):同时注入故障的位置集合,是注入位置求解的单个结果的形式化表示。
[0098] 故障注入点集合(Injection Point Set,IPS):注入位置求解的所有结果形式化表示为IP集合,即IPS。
[0099] 有效故障注入点(valid IPS):使应用产生异常的故障注入点。
[0100] 下面结合附图对本发明进行详细说明。
[0101] 如图1所示,本发明一种面向微服务应用的失效测试工具包括:产生并收集调用链、求解注入位置、故障注入与异常检测、故障恢复模式检测。其中求解注入位置过程应用一种基于布尔可满足性约束的注入位置求解方法,和故障注入与异常检测过程共同完成自动化失效测试的主要流程;模式检测过程解决了故障恢复行为分析问题。
[0102] 下面详细介绍各部分的实现方式:
[0103] 本发明中调用链产生与收集过程的具体实现如下:
[0104] 调用链产生与收集过程针对不同待测应用设计测试用例(Test Case),并且保证并发请求中不同测试用例的比例稳定,从而达到模拟真实用户流量的目的。在测试过程中,负载发生装置根据测试用例的内容保持并发的、持续产生的请求。
[0105] 为了贴近线上测试环境,负载发生装置将产生正常的请求和测试请求。测试请求通过包含特定请求头(HTTP Header)的方式区别于正常请求。测试用例引导负载发生的过程如图3所示。测试用例首先根据概率决定是否产生测试请求,然后由负载发生线程判断是否存在尚未执行的负载发生操作,如果已经完成了测试用例中的所有操作则结束,否则根据决策结果决定是否指定特定请求头。最后,负载发生线程生成参数并发出请求,触发业务逻辑,在获得响应后执行下一轮循环,直到测试用例中所有步骤完成,则本次负载发生过程结束。
[0106] 本发明使用Jaeger作为调用链跟踪与存储工具。利用该工具,算法可以收集测试请求产生的调用链,并作为最原始的输入数据。然而,该数据中存在大量类似的记录,需要进行分类处理。例如:对于车票查询业务而言,假设存在两个查询记录,分别为查询天津到北京的车票和查询北京到天津的车票。虽然参数不同,但二者在应用中的处理过程相同,所以这两个请求是相似的。
[0107] 调用链产生与收集过程将具有相同处理过程的请求分为一类,具体而言,按照调用链中的结构进行分类。如果两个请求的调用链完全相同,那么他们的处理过程相同,被视为一类。通过分类操作,约束求解过程将只针对不同的调用链进行分析,提高了测试过程的效率。
[0108] 如图4所示,求解注入位置部分的具体实现如下:
[0109] 故障注入空间的规模以幂函数的速度随着服务数量的增多而显著增大。大型微服务应用具有数以百计的微服务。逐个尝试所有注入方案是不可行的,有必要寻找一种高效的故障注入位置生成与优化方法。本发明基于约束求解的方法实现了自动高效求解注入位置。自动化注入位置求解与优化过程以调用链为输入,包括三个步骤:构造模型、基于Z3求解模型以及优化解集,最终得到待测故障注入位置的集合。下面依次针对三个部分的实现细节进行阐述。
[0110] 构造模型的实现步骤如图5所示:
[0111] (1)遍历相同请求的每一个调用链,并且将调用链中的每个调用过程编码为布尔变量。变量值表示是否在该调用过程注入故障。
[0112] (2)同一调用链中的布尔变脸通过析取表达式连接,构造析取表达式。约束表达式的含义是注入的位置必须使调用链中的包含至少一个故障,从而保障故障的有效性。
[0113] (3)同一请求的不同调用链产生的析取表达式通过合取符号连接,构造合取表达式。表达式的含义是注入的位置必须同时使同一请求产生的不同调用链包含故障。微服务应用为了使应用可以保持“一直在线”的状态,实现了大量冗余调用。这些调用过程只在目标调用过程发生故障后才会影响用户请求。一方面,只在冗余调用注入故障将导致注入无效;另一方面,只在目标调用注入故障将导致应用以冗余调用处理用户请求,需要进一步测试。本步骤保障了同时在同一请求的所有冗余路径注入故障,在拥有复杂冗余调用实现的大型微服务应用中优势格外明显。
[0114] Z3约束求解器由微软设计与实现,可以高效地验证约束表达式是否可满足并且求解约束表达式的单一最简解。本发明中基于Z3求解约束表达式的步骤如图6所示:
[0115] (1)利用Z3判断表达式是否可满足。如果可满足,则进入步骤(2);否则,进入步骤(5)。
[0116] (2)利用Z3求解表达式的单一最简解,并将其添加至解集。
[0117] (3)根据步骤(2)求得的最简解构造约束表达式,并且对约束表达式取反,得到新的子表达式。
[0118] (4)将步骤三得到的子表达式和原表达式用合取符号拼接,构成新的待解约束表达式,再次进入步骤(1)。本步骤的目的是修改约束条件,明确规定之后求得的最简解不能是已有最简解。
[0119] (5)输出解集,作为约束表达式求解的结果,逻辑上表示故障注入点集合。
[0120] 对于复杂的微服务应用,故障注入空间巨大,利用上述求解方法虽然可以有效的减小故障注入点的规模,但仅考虑了微服务之间的调用路径信息,缺少对故障注入后路径传播信息以及对故障注入结果等信息的有效利用,通过约束求解得到的故障注入点集合中仍然可能存在冗余注入点的情况。为了减少冗余故障的注入,进一步提高故障空间探测的效率,本发明提出两种策略对待测故障注入点集合进行消减。
[0121] (1)对于复杂的用户请求,由于涉及的服务调用较多,通过约束求解得到的故障注入点数量也较多。如果逐个进行注入,则效率较低。注入故障后,异常信息随响应传播的过程将停止于包含故障恢复逻辑的服务处,如果在异常信息传播导致崩溃的服务处注入相同故障,则异常信息的传播仍将停止于同一个包含故障恢复的服务处,无法发现新的测试结果,所以本发明不再测试只在异常信息传播路径上注入故障的故障注入点。该策略在调用链较长且依赖少数关键服务处理故障的情况下格外有效。在实际的开发过程中,长调用链中的每个服务都包含复杂故障恢复逻辑的情况非常少,通常依赖于少数关键服务进行故障恢复,所以该策略的设计与实现具有很强的必要性。
[0122] 策略1的实现步骤如图7所示,首先根据历史注入结果的调用链分析故障传播导致的异常调用过程,然后遍历待测故障注入点,将只在异常调用过程注入故障的故障注入点从待测故障注入点集合中删除。
[0123] (2)在根据约束求解得到的故障注入点集合进行故障空间探测的过程中,可能会出现当前待探测的故障注入点在历史探测中曾经被注入的情况,此时需要根据历史故障注入结果进行分析以避免故障的重复注入。以图8中的故障空间探测过程为例。该用户请求触发四个服务:业务服务、缓存服务、查询服务以及数据库服务,分别可以抽象为varprocess、varcache、varquery、vardatabase。在无故障发生的情况下,应用处理请求的过程如调用链1所示,包含调用过程1-1以及调用过程1-2。利用3.4.1和3.4.2小节提出的求解方法可以得到三个IP:{varprocess}、{varquery}、{vardatabase},其中有效IP为{varprocess}和{varquery}。在对数据库调用注入故障后,应用处理请求的过程如调用链2所示。利用调用链1和调用链2,再次求解得到三个IP:{varprocess}、{varcache,varquery}、{varcache,vardatabase}。其中{varprocess}已经测试,所以不再被重复测试。{varcache,varquery}包含有效IP{varquery},触发的故障恢复逻辑和{varquery}相同,所以也不再重复测试,即基于故障注入结果的优化策略。最终第二次产生的IPS中只有{varcache,vardatabase}将被测试,提升了测试效率。
[0124] 策略2的实现步骤如图9所示,首先将有效故障注入点和待测故障注入点转换为字符串,形成两个字符串集合,然后基于KMP算法,去除所有包含有效故障注入点字符串的待测故障注入点字符串。
[0125] 如图10所示,故障注入与异常检测部分的具体实现如下:
[0126] (1)本发明定义了两种基本类型的故障:返回错误信息(Error)以及消息延迟(Delay)。返回错误信息(Error)指HTTP响应结果包含非200系列(200,201等)的响应码,被抽象表示为Abort(code),其中code表示返回的HTTP码,取值符合RFC2616标准。消息延迟(Delay)指服务长时间无法完成请求过程,导致用户或上游服务长时间无法得到响应信息,被抽象表示为Delay(duration),其中duration表示响应的延长时间。基于Abort与Delay的组合,方法进一步支持模拟服务过载、挂起、断开连接以及崩溃等更加复杂的故障类型,如表3.1所示。以过载故障为例,使目标服务的80%流量呈现Delay(10s),20%流量呈现Abort(503),则目标服务将呈现过载状态。在故障注入过程中,方法将依次产生所有故障场景,直至发现故障恢复缺陷或应用可以应对的所有故障场景。
[0127] 表3.1故障场景实现
[0128] Table 3.1 The Fault Scenario Implementations
[0129]
[0130] (2)注入故障后,本发明提供了两种异常检测方式:内置断言验证与人工指定验证内容。前者利用多种通用机制对应用的响应结果进行验证;后者为验证条件提供了灵活的扩展能力。
[0131] 首先,方法以2-5-10原则为依据,以5秒为阈值,依据响应时间判定请求能否被正常处理。如果响应时间大于5秒,则判定应用的故障恢复逻辑存在缺陷。如果响应时间正常,方法基于响应码对响应结果的语义进行判断。如果响应码以非200系列(200、201等等)的数字形式存在,则判定请求处理异常,即应用的故障恢复逻辑存在缺陷。如果响应码正常,方法利用请求头“Content-Type”识别JSON数据格式,然后针对JSON格式的响应结果,尝试基于字典抽取目标字段,最后通过该字段的值判断请求是否被成功处理。如果以上内置方法无法检测出异常,则执行用户指定的断言,进行最后的异常检测过程。
[0132] 表3.2故障处理的分类
[0133] Table 3.2 Kinds of Fault Handling
[0134]
[0135] (3)如果应用在注入故障后,仍然可以正常处理用户请求,则表明应用具有冗余的计算路径。本发明将对调用链进行更新操作。根据调用链的组成,故障处理方式可以分为三种情况,如表3.2所示。第一种情况,目标服务发生故障后,上游服务请求失败并更改调用目标,调用具有和目标服务类似功能的服务(称为备份服务或冗余服务)。该情况下,调用链同时包含对故障服务的调用和对备份服务的调用。第二种情况,目标服务发生故障后,上游服务经历多次失败的尝试,不再尝试请求目标服务,直接请求备份服务。该情况下,调用链只包含对备份服务的调用,不包含对目标服务的调用。第三种情况,目标服务发生故障后,上游服务经历多次失败的尝试,不再请求包括目标服务和备份服务在内的任何服务。该情况下,调用链既不包含对目标服务的调用又不包含对备份服务的调用。
[0136] 对于第二和第三种情况,调用链中每个服务都在请求的处理过程中发挥了作用。然而对于第一种情况,由于已经在目标服务注入故障,目标服务无法正常提供相关功能,在请求的处理过程中并未发挥作用,所以对于第一种情况,调用链去掉目标服务后才能合理解释请求的处理过程。
[0137] 本发明利用Jaeger收集注入故障后的调用链,然后去除调用链中的对故障服务的调用过程并更新调用链,为之后的故障注入位置求解过程提供更准确的输入信息。该过程对故障注入空间探测方法至关重要。更新后的调用链是自动调节注入位置的重要依据。
[0138] (4)本发明利用Istio框架实现了通过撤销对网络请求配置的方式使服务快速从故障状态恢复。该方式不需要修改应用源码和直接依赖的运行环境,具有代价小、恢复速度快等优点,对基于不同技术实现的微服务应用具有通用性。
[0139] 故障恢复模式检测部分包括超时模式检测、重试模式检测、熔断模式检测以及船舱模式检测。对于应用无法处理的故障场景,本发明基于比对正常数据和异常数据的基本思路,从多个微服务故障恢复模式的角度分析应用的故障处理行为,辅助测试人员快速了解故障恢复逻辑,加快缺陷的修复过程,具体实现如下:
[0140] (1)超时模式分析方法的实现
[0141] 在理解与超时相关的行为时,开发者通过比较正常响应时间和异常响应时间,达到推测超时阈值的目的。对于复杂调用链,该过程将消耗开发者大量时间和精力,所以本发明自动化执行该过程,为开发者提供具有明显变化的响应时间数据,辅助开发者解决超时阈值冲突等问题。
[0142] 超时模式分析过程如图11所示。基于有效故障注入点,本发明首先注入Delay(20s)故障,然后根据调用链信息统计响应时间t'src,tar,随后撤销故障并以同样的方式统计正常响应时间tsrc,tar。最后比对tsrc,tar与t'src,tar,输出存在明显变化的响应时间。需要指出,调用链中的超时阈值通常小于10秒,所以本发明选择注入Delay(20s)可以有效触发超时现象。
[0143] 本发明基于高斯分布定义响应时间的波动区间[tsrc,tar-σ,tsrc,tar+σ],其中σ为正常响应时间的标准差。如果响应时间tsrc,tar在区间[tsrc,tar-σ,tsrc,tar+σ]中,本发明认为源服务src到目标服务tar的调用过程未受故障影响;否则认为调用的响应时间异常,很有可能和超时阈值的设置相关,所以输出相关信息。
[0144] (2)重试模式分析方法的实现
[0145] 和超时模式类似,为了理解应用的重试逻辑,开发者通过比较正常调用链和带有重试行为的调用链,达到推测重试次数的目的。对于复杂的调用链,该过程消耗开发者大量时间和精力,所以本发明自动执行该过程,为开发者提供服务之间的重试次数,辅助开发者发现非预期的重试行为。
[0146] 本发明首先基于有效IP,注入Abort(500)故障,然后分别遍历正常情况下的调用链与异常情况下的调用链,计算服务间的调用次数,随后分析调用次数有明显变化的服务,相关调用过程即为重试过程,最后统计重试过程的次数并输出相关信息。
[0147] (3)熔断模式分析方法的实现
[0148] 本发明首先获取正常情况下的调用链,然后基于有效故障注入点,注入Abort(500)故障,获取相同请求在异常情况下产生的调用链,最后基于树型比对的算法计算熔断位置。确定熔断位置的过程以正常情况下的调用链和注入故障后的调用链为输入,同时递归遍历两个调用链中都存在的调用过程,遍历过程中收集正常情况下存在但注入故障后不存在的子调用过程。消失的调用过程代表被熔断的局部调用,其对应的上下游服务将以熔断位置的形式输出给开发者。
[0149] (4)船舱模式分析方法的实现
[0150] 开发者需要推测多个吞吐量变化趋势的关系,从而确定接口对于共享资源的影响。本发明对变化趋势进行简单的分析,辅助开发者理解资源共享行为。本发明首先确定服务间的依赖关系,然后在下游服务注入Delay(20s)故障。Delay(20s)使目标服务的响应时间变长,所以在一定时间内,上游服务到目标服务之间的连接数将增多,消耗相关资源。本发明随后保持稳定的并发用户请求,监控上游服务到其他下游服务之间的吞吐量。如果吞吐量大幅降低,则相关服务彼此影响,相关接口可能存在共享资源的情况。
[0151] 提供以上实施例仅仅是为了描述本发明的目的,而并非要限制本发明的范围。本发明的范围由所附权利要求限定。不脱离本发明的精神和原理而做出的各种等同替换和修改,均应涵盖在本发明的范围之内。