背景

基本上在公司里的项目都是采用了微服务架构,用微服务架构长时间运行,局部会出现系统故障是不可避免的。如果发生故障时不能进行有效反应,系统的可用性将极大地降低,也会对用户体验造成极大的伤害

为什么需要故障演练

为验证被测服务的高可用,模拟依赖服务或应用实例的异常场景,不限于实例下线、连接中断、返回异常等,一次验证被测服务是否存在闭环的策略机制。

通过故障演练,至少可以在以下几方面获得收益:

  1. 提前发现、预测生成环境可能出现的部分故障,快速响应,防止故障扩散。

  2. 在演练中识别系统和应用程序的风险和漏洞,取必要的纠正措施。

  3. 改进团队响应流程 , 故障演练可以促进团队沟通、理解和协作,完善生产环境的排障流程。

介入时机

项目业务功能稳定之后(接口测试之后、功能测试之后)、专项的测试需求。

先选定测试对象,再模拟依赖服务的故障。

尽可能覆盖被测对象下游所有依赖对象的异常场景(数据源、中间件、微服务实例节点、三方服务)

如何进行故障演练测试

通过模拟依赖服务的异常行为,验证被测服务是否具备特殊场景的高可用。

测试内容:

  • 依赖服务返回异常状态码(被测服务的期望值:被测服务返回服务端异常描述)

  • 依赖服务返回超时(被测服务的期望值:被测服务有超时处理机制,触发机制时返回超时信息的描述)

  • 依赖服务异常下线(被测服务的期望值:保持服务的可用性,返回服务异常的描述)

  • 被测服务应用下的多实例场景,其中一个实例节点挂掉(预期值:会把已挂掉的实例节点中分发的流量转发至其他节点,以及应用有自动的容灾策略,实例扩容、旧实例回收、流量控制)

场景模拟的测试工具:fiddler/charles/burpsuite/自动化桩,需要代理被测服务的服务器。

测试用例编写

  1. case1:依赖服务返回异常状态码,需要前置了解依赖服务存在的所有状态码,进行全覆盖(相当于有多少状态码就有多少个用例)

    • 用例内容:

      • 在被测服务请求依赖服务时,模拟依赖服务返回XXX状态码

    • 期望值:

      • 被测服务端对外返回5XX状态码

      • 返回体不能出现报错代码、暴露项目路径

      • 被测服务不会继续处理当前事务的下游逻辑

      • 异常处理后再进行一次正向的处理(不进行状态码篡改),被测服务是否可以正常的处理成功

  2. case2:依赖服务返回超时

    • 用例内容:

      • 在被测服务请求依赖服务时,模拟依赖服务返回超时场景(参考时间建议:60s)

    • 期望值:

      • 被测服务有依赖服务的超时处理机制

  3. case3:依赖服务异常下线

    • 用例内容:

      • 在被测服务请求依赖服务前,模拟依赖服务下线后再发起请求。

    • 期望值:

      • 被测服务端对外返回5XX状态码

      • 返回体不能出现报错代码、暴露项目路径

      • 被测服务不会继续处理当前事务的下游逻辑

  4. case4:依赖服务宕机(网络问题、运维问题)

    • 用例内容:

      • 在测试环境模拟依赖服务宕机行为,如果有操作权限直接kill -9依赖服务的进程

      • 如果没有需要找开发配合模拟场景(支持配置更改依赖对象)

    • 期望值:

      • 被测服务有对应的处理方法。

  5. cae5:依赖服务的数据处理情况

    • 用例内容:

      • 如果是查询业务,可能需要考虑依赖服务返回空数据、单数据、多条数据的情况,

      • 根据不同的业务形态补充各类型的约束条件、数据处理case

    • 期望值:

      • 每种业务处理数据返回情况被测服务都可处理

故障演练的价值

测试的优先级:

测试的价值:

  • 保障被测服务的高可用

    • 部分容灾策略的前置校验,如果遇到实例异常下线直接导致上游服务崩溃或宕机,这时即使及时扩容新的服务实例也需要全流程重新部署服务。

  • 如果依赖对象不稳定时,是否有闭环的处理逻辑。