Asjdf

一只在杭电摸鱼的小火鸡

分布式系统测试工具 muxy 初探

2023-07-17 大约1847字 预计阅读4分钟

# 前言

本篇文章主要简单介绍分布式系统测试工具 muxy 工具,在介绍前,我想先谈谈分布式系统测试。

# Coding is easier than testing

编程比测试简单。我认为一个程序你把它写出来不是最难的,把它测好才是最难的。真的这么夸张吗? 我想从一个简单的 HelloWorld 程序来谈谈一个系统的稳定运行所需要的条件。

# 一个普通的 HelloWorld

我们需要考虑来自以下几个方面所造成的 Bug:

  • 编译器
  • 链接器
  • 虚拟机(可能需要考虑)
  • 系统

一个 HelloWorld 能够每次都正确运行已经是一个奇迹了,为什么呢?首先,编译器得没 bug,链接器得没 bug ;然后我们可能跑在 VM 上,那 VM 还得没 bug;并且 Hello world 那还有一个 syscall,那我们还得保证操作系统没有 bug;到这还不算吧,我们还得要硬件没有 bug。所以一个最简单程序它能正常运行起来,我们要穿越巨长的一条路径,然后这个路径里面所有的东西都不能出问题,我们才能看到一个最简单的 Hello world。

来到分布式系统,路径又将延长。

# 一个实现RPC的 HelloWorld

  • 协调器 (zookeeper, etcd)
  • RPC 实现
  • 网络协议栈
  • 编解码器以及其各语言的程序生成器

做分布式,很难绕开服务发现这个点,或多或少会用到诸如 zookeeper、etcd这类软件。在大家的印象里,这类软件应该很稳定吧?但翻阅他们的 release note,其中还是会包含 bug fix,也就是说在我们平时印象中非常稳定的东西其实一直在升级,每次升级都会有 bug 修复。很显然我们是幸运的,大部分时候我们并没有碰上那些 bug。再往前走,如果大家深度使用 RPC,如 gRPC,那么其实你会意识到这个被大量应用使用的库的 bug 还是挺多的。还有系统网络协议栈,就是 Linux 的 TCP 协议栈同样会爆出 checksum 存在问题,这都是印象中永远不会出问题的。

因此一个程序/系统能够正常运行,是一个件非常幸运的事情。那为什么一个不完善的系统在通常情况下能够顺利运行呢?因为在程序的测试阶段,我们的测试用例已经覆盖了“正确”的路径,也就是说测试时已经在理想的情况进行了测试,但是其中有很多“错误”的路径(网络错误、磁盘错误、异常输入)我们并没有测试到。

# 请使用自动化测试

为什么要强调使用自动化测试?

  1. 让开发人员能够快速得到测试结果
  2. 让开发人员一次性执行所有单元测试
  3. 在睡觉的时候发现bug

为了让过去发现并修复的 bug 不再产生,我们应在每次处理bug之前应创建一个单元测试用于复现该bug,这样在后续的测试流程中将会检查程序是否存在同样的 bug。

但逐渐增加的单元测试也会增大测试工作量,因此我强调要使用自动化测试来帮助你检测程序的健壮性。有了自动化测试,开发人员才能随心所欲创建大量的单元测试用于检查程序健壮性。

# 该怎么测试?

  1. 错误注入
  2. 模拟一切

模拟一切就是尽可能完整的模拟一个程序运行所需的外部依赖。这样我们就可以在任何时间、场景下注入各种错误,如我们可以让程序发出的网络请求延迟、丢包,或是可以在程序尝试写入磁盘的时候阻止其写入,告诉程序发生磁盘故障等问题。

如果一个程序保持网络连接的时间为30秒,那么31秒后程序会发生什么情况?是否会尝试在已断开的网络连接上进行通信,还是会重新建立连接?

# 如何让 Muxy 帮助你进行测试?

Muxy 是一个用于模拟网络故障代理,可在4、5、7层模拟网络。

如果你正在构建分布式系统,Muxy 可以帮助您测试弹性和容错模式。

由于原项目在19年就停止了维护,我自己维护了一个分支并更新了相关依赖版本、重新为多平台进行了构建,希望能够帮助大家进行测试,也欢迎帮助我完善这个工具。

# 使用 Muxy

Muxy 通常有两种使用方式:

  1. 在本地开发中查看您的应用程序在某些条件下如何响应
  2. 在测试套件中自动化弹性测试

# 5 分钟示例

  1. 安装Muxy

  2. 创建配置文件config.yml

    # 配置代理来转发/干扰您发往的www.onegeek.com.au的请求。
    # 此示例添加了 0.5 秒的响应延迟。
    proxy:
        - name: http_proxy
        config:
            host: 0.0.0.0
            port: 8181
            proxy_host: www.onegeek.com.au
            proxy_port: 80
    
    # Proxy plugins
    middleware:
        - name: http_tamperer
        config:
            request:
            host: "www.onegeek.com.au"
    
        # Message Delay request/response plugin
        - name: delay
        config:
            request_delay: 1000
            response_delay: 500
    
        # Log in/out messages
        - name: logger
  3. 使用您的配置运行 Muxy: muxy proxy --config ./config.yml

  4. 通过代理向 www.onegeek.com 发出请求:time curl -v -H"Host: www.onegeek.com.au" http://localhost:8181/。将其与直接发送到网站的请求进行比较:time curl -v www.onegeek.com.au ——它应该快大约 0.5 秒。

更多功能还请移步Muxy文档

# Muxy 作为测试套件的一部分

  1. 创建应用程序
  2. 构建容错能力(例如使用 Hystrix 之类的东西)
  3. 创建集成测试
  4. 运行 Muxy,配置代理(例如 HTTP)以及一个或多个症状(例如网络延迟、分区或 HTTP 错误)
  5. 将您的应用程序指向 Muxy
  6. 运行测试并检查系统是否按预期运行

# 提示

Muxy 是一个有状态的系统,会干扰您的低级(系统)网络接口,因此无法与其他测试并行运行。 还建议在容器/虚拟机中运行,以避免意外后果(例如中断主机的 Internet 访问)。

闽ICP备2022001901号-1 公安网备图标闽公网安备35030302354429号

主题 atom-hugo-theme