2017年中,我参与了一个亚太地区互联网公司并购的项目,客户收购了亚太地区 7 个国家的同行业互联网企业和产品。我作为其中的 DevOps 咨询师和 DevOps 工程师,和客户一起完成并购后的产品迁移和技术能力提升的设计、实施和培训。
客户希望采用新的统一产品,并根据不同地区的业务特色进行一些定制,与此同时,需要进行数据迁移以保证业务可以继续运行。其中一个很关键的步骤是把原系统的 URL 通过重定向的方式到新的产品中,因为有很多的第三方链接和搜索引擎依然保留了原系统中的链接。
初步统计了一下,将近有3000多个 URL 需要重定向,光是规则和正则表达式就写了 400 多条(没有统一规则的 URL 害死人啊),这就引发了一个问题:我该如何验证这些规则和覆盖这些 URL ?此外,大量的重定向不光对用户来讲不是很好的体验,如果我要优化这些规则,我如何保证我当前的转发规则不被破坏?
最早,我们写了一个 Shell 脚本,用 curl
命令来验证这些 URL,最初只需要验证 200 条就可以满足需求,时间也不到两分钟。后来,我们采用了一个 Excel 文件来跟踪这些 URL,产品经理只需要把新的重定向 URL 补充到上面,我们就依据这些 URL 来开发 nginx 的重定向规则。
这让我想到了 TDD 的红绿模式:先写出一个自动化测试用例,然后修复这个自动化测试用例。更好的是,有了自动化的测试做保护,你可以放心和安全的对代码(Nginx)进行重构。
此外,随着更多的 URL 需要重定向,这个数字在不断的增加。原先的 Shell 脚本执行的时间也从最初的 2 分钟增长到了15分钟。
现有的工具满足不了要求,一怒之下,我决定开发一个自己的工具。它必须具备以下特点:
于是,我在一个周末的时间用 Python 写下了 vivian
: 一个多线程的批量自动化重定向验证工具。
它把原先的 15 分钟的验证时间缩短到了 17 秒,效率提升了 5294 % !!
后来,我把测试用例集成到了代码库里。并把 vivian 提交到了 pipy,这样我就可以通过 pip 在初始化 CI 上安装了。也减少了代码库中减少了一个需要维护的脚本。
选择 Python 的原因主要是因为相较于 Ruby, Go, Java, NodeJS 来说。Python 的语言环境比较稳定,几乎每种 Linux 都包含 Python 的运行环境,且容易安装和集成。
如果你对该工具感兴趣,欢迎在 github 上围观:https://github.com/wizardbyron/vivian
安装:
pip install vivian
使用:
vivian -f example.csv
test.csv 非常简单,第一列是源 URL,第二列是目标 URL。例如:
http://www.github.com, https://github.com/
http://www.facebook.com, https://facebook.com/
采用 csv 文件的目的主要是方便使用 Excel 和文本工具编辑。
之后会得出下列结果:
vivian -f example.csv
load test case from example.csv
2 cases loaded running in 2 threads
verifying http://www.github.com to https://github.com/
verifying http://www.facebook.com to https://facebook.com/
Failed cases:
============================================================
line: 2
origin: http://www.facebook.com
dist: https://www.facebook.com/
expect: https://facebook.com/
status: 200
redirect_count:1
------------------------------------------------------------
1/2 PASS in 5.8494720458984375 seconds
第一行输出提示测试用例文件的路径。
第二行输出提示测试用例数量和线程数量。你也可以通过增加 -n 来指定线程的数量,默认线程数量等于 CSV 文件记录行数。如果文件过大,请限制线程数量,否则线程创建开销会影响测试机性能。此外,过多的并发访问也会发起应用的流量保护机制。没有流量保护的应用则会 Crash。
第三行到第四行列出了需要验证的 URL。
第五行开始就是失败的测试用例信息:
失败用例的第一行就是测试用例所在的文件行号。
失败用例的第二行是测试用例测试的源 URL。
失败用例的第三行是访问测试的 URL 的实际目标 URL。
失败用例的第四行是期望得到的 URL。
失败用例的第五行是访问测试用例源 URL 最后得到的 HTTP 状态。
失败用例的第六行是访问测试用例源 URL 到最后结果之间的 重定向次数,有了这个数字我们可以优化 URL。
最后一行表明有多少个用例通过了测试,同时统计了完成这些测试的总时间。
以下是我总结的使用 vivian 的最佳实践场景,希望能对你的 web 服务器维护工作起到帮助。
Vivan 是用 Python 编写的,这意味着你可以在自己的 CI 服务器上(大多是 Linux)很容易的安装 vivian,在部署完成后用 vivian 执行代码中的测试用例,这相当是对 Nginx 规则开发的回归测试——不会影响到以前的 URL 重定向。于此同时也是一种冒烟测试,如果测试失败,Nginx Server 是有问题的。这样可以避免一些修改破坏当前的生产环境。
在这种模式下,你需要先把需要重定向的案例写到文件里,这时候运行 vivian 肯定会失败。之后你就可以根据案例编写重定向规则。甚至可以优化合并一些正则表达式,因为有自动化测试保护。你可以放心的将验证过的 nginx 部署到生产环境中。
用 Dev 的方式处理 Ops 的工作,也算一种 DevOps 吧!?
我们知道,每一次重定向都会给客户端带来额外的访问开销,这对用户体验是一种灾难。redirect_count
记录了重定向的次数,并且给出了最初和最终的 URL,我们可以利用这些信息构造更加简单和直接的规则,优化重定向。