你好,我是温铭。

专栏更新到现在,OpenResty 第三版块 OpenResty 测试篇,我们就已经学完了。恭喜你没有掉队,仍然在积极学习和实践操作,并且热情地留下了你的思考。

很多留言提出的问题很有价值,大部分我都已经在 App 里回复过,一些手机上不方便回复的或者比较典型、有趣的问题,我专门摘了出来,作为今天的答疑内容,集中回复。另一方面,也是为了保证所有人都不漏掉任何一个重点。

下面我们来看今天的这 5 个问题。

问题一:如何搭建测试的网络结构?

Q:跑 wrk 的客户端,是应该放在外网上的机器上,还是和服务端同一局域网内的机器上呢?这两者,哪个更有性能测试意义?

A:其实,对于测试 web 相关的服务来说,选择正确的测试工具,只能算得上是一个好的开端,如何搭建测试的网络结构,也是后续的重要一环。

一般来说,我们肯定希望排除所有网络的干扰,单独测试出服务的性能极限来。出于这个目的,我们可以有两种搭建网络的方法来做压测。

  • 第一种方法,把 wrk 和服务端程序都部署在同一台性能比较好的机器上。比如,我们在 Nginx 中开启 8 个 worker,剩下的几个 CPU 资源分给 wrk。这样一来,就只有本地的网络通信,可以把网络的影响降到最低。
  • 第二种方法,用专门的路由器搭建一个局域网,把 wrk 所在的机器和服务端所在的机器连在一起。

之所以不推荐你在已有的网络中直接测试,是因为大部分的网络中都存在交换机和防火墙,它们可能会对大流量的压测进行限制,造成测试结果的不准确。

另外,关于性能测试工具,我还想再多提几句。性能测试工具可能存在 Coordinated Omission 问题,在分析工具的延时数据的时候,你一定要特别留意。

简单地说,Coordinated Omission(协调遗漏)是指,在做压力测试时,对于响应来说,只统计发送和收到回复之间的时间是不够的,这只是服务时间,这样统计会遗漏很多潜在的问题。因此,我们还需要把测试请求的等待时间也计算在内,这个整体才算是用户关心的响应时间。当然,如果你的服务端程序可能会出现阻塞,一定需要考虑这个问题,否则就可以忽略掉了。

问题二:test::nginx 可以测试 ssl 相关功能吗?

Q:ssl 相关功能,用test::nginx是不是测不了?

A:事实显然不是这样的,test::nginx 可以测试 ssl 的相关功能,你可以参考 https://github.com/iresty/apisix/blob/master/t/node/ssl.t,这个测试案例文件测试了 ssl 证书的全过程。你可以看到,测试案例使用 Lua 代码,来读取本地证书的公钥和私钥;然后,再通过 http API 设置好证书;最后,用 cosocket 来 ssl 握手和访问,验证证书是否生效。

其实,不仅仅是 ssl 这个功能,只要是 OpenResty 中包含的功能,使用 test::nginx 都是可以覆盖的。

当你不确定某个功能用 test::nginx能不能实现时,可以先去 lua-nginx-module 和其他的 OpenResty 开源项目的测试案例集中搜索,一般都能找到对应的示例。我也是用这种方法来解决这类问题的,毕竟,test::nginx的可玩性和变化性比较大,总有一些意想不到的使用组合和奇技淫巧在等着你发掘。

问题三:DSL 究竟是什么?

Q:DSL 的翻译是领域专用语言吗?文中讲了它是领域小语言,但我搜这个词没有搜到,只搜到了领域专用语言 DSL(Domain Specific Language)。

A:DSL 确实是领域专用语言的缩写,而小语言是 DSL 的俗称。之所以在前面加了一个“小”字,是因为 DSL 的目的和常用的开发语言不同,它不是为了解决通用领域的需求,而是要解决某个领域的需求。最著名的 DSL 就是 SQL,结构化查询语言,用在数据库领域。

至于test::nginx,它其实是为了解决 Nginx 和 OpenResty 的测试需求而创造出来的 DSL。实际上,OpenResty 的作者发明了很多小语言,这种 DSL 的思路,也将会给 OpenResty 社区带来不少新的尝试和解决方案。不过,正如之前文章中提到的一样,DSL 是把双刃剑,能否给最终使用者带来生产力的提升,才是衡量 DSL 是否有价值的主要标准。

问题四:test::nginx的安装问题

Q:在执行完git clone后,是否需要执行下面的命令,才能安装test::nginx呢?

1
2
3
4
5
6
7
8

cd test-nginx

perl Makefile.PL

make

sudo make install

A:事实上并非如此,这里其实你可以参考一些开源项目中 travis 的做法。

第一步,先通过包管理器安装 https://github.com/iresty/apisix/blob/master/.travis/linux%5Frunner.sh#L20

1
2

sudo cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1)

第二步,git clone 最新的 test::nginx https://github.com/iresty/apisix/blob/master/.travis/linux%5Frunner.sh#L35

1
2

    git clone https://github.com/openresty/test-nginx.git test-nginx

第三步,用 prove 命令的时候,把 test nginx 的目录包含进去:

1
2

prove -Itest-nginx/lib -r t

前面我也提到过,OpenResty 以及周边的项目,安装的最佳指南都存在于 travis CI 中,而不是文档中。这一点可能与其他项目的做法不同,主要是因为,OpenResty 自己维护了一些周边项目的 fork 或者特定版本;同时,OpenResty 也是强依赖 travis CI 的。所以,你应该按照 travis CI 中构建的方法来使用和测试 OpenResty,才能保证和官方一致。

问题五:ab 测试工具到底好不好用?

Q:我怎么记得春哥在 Google Groups 里,多次提到 ab 是当前最佳测试工具呢?

A:文章中我也提到过了,单从工具特性来说,ab 并不是一个好的性能测试工具。因为它不能够产生足够大的请求压力,而现在的服务端程序性能却已经非常强悍了。我们在 test::nginx 中确实会用到 ab,而不是 wrk,这是因为在 TEST_NGINX_BENCHMARK 模式下,test::nginx 会根据 HTTP 协议版本,选择使用 ab 或者 weighttp,来作为压力测试的工具。

另外,希望你注意到的是,互联网技术的更新换代非常快,我们身在其中的每个人,都需要及时更新自己的知识和技能数。比如说test::nginx 的这个选择,在我看来现在已经需要更新了,而春哥当时可能还不知道 wrk 的存在。当然,也许再过一段时间,会有比 wrk 更好的性能测试工具出现,我们自然也应该抱着积极开放的心态去学习和选择。

今天主要解答这几个问题。最后,欢迎你继续在留言区写下你的疑问,我会持续不断地解答。希望可以通过交流和答疑,帮你把所学转化为所得。也欢迎你把这篇文章转发出去,我们一起交流、一起进步。