极客时间已完结课程限时免费阅读

30 | 答疑(三)如何搭建测试的网络结构?

30 | 答疑(三)如何搭建测试的网络结构?-极客时间

30 | 答疑(三)如何搭建测试的网络结构?

讲述:温铭

时长07:52大小7.20M

你好,我是温铭。
专栏更新到现在,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呢?
cd test-nginx
perl Makefile.PL
make
sudo make install
A:事实上并非如此,这里其实你可以参考一些开源项目中 travis 的做法。
sudo cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1)
git clone https://github.com/openresty/test-nginx.git test-nginx
第三步,用 prove 命令的时候,把 test nginx 的目录包含进去:
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 更好的性能测试工具出现,我们自然也应该抱着积极开放的心态去学习和选择。
今天主要解答这几个问题。最后,欢迎你继续在留言区写下你的疑问,我会持续不断地解答。希望可以通过交流和答疑,帮你把所学转化为所得。也欢迎你把这篇文章转发出去,我们一起交流、一起进步。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 1

提建议

上一篇
29 | 最容易失准的性能测试?你需要压测工具界的“悍马”wrk
下一篇
31 | 性能下降10倍的真凶:阻塞函数
unpreview
 写留言

精选留言(4)

  • 猪小擎
    2022-04-06
    更好不是更换一项技术的理由,好得多才是,如果没有50%左右的提升,那么就没必要更换。
  • helloworld
    2019-08-04
    ngx.say(type(ngx))输出table ngx.say(cjson.encode(ngx))为什么无法序列化ngx,报错提示不能对函数做序列化。 老师,这个是什么原因呢

    作者回复: 你是指为什么一个类型是 table,一个报错时候的类型是function? 首先 ngx 确实是一个 table,其次 cjson 里面报错的源码在这里 https://github.com/mpx/lua-cjson/blob/master/lua_cjson.c#L457: luaL_error(l, "Cannot serialise %s: %s", lua_typename(l, lua_type(l, lindex)), reason); 它是用 lua_typename(l, lua_type(l, lindex)) 来判断数据类型的。我估计 lua_type 判断 ngx 的时候出错了。但我并没有跟到代码中去确认,你可以看下具体的判断代码。

  • helloworld
    2019-08-02
    local table_nkeys = require "table.nkeys" foo = {1, 2, 3, "bar"} item_count = #foo item_count_ = table_nkeys(foo) 老师,这两种获取table元素个数的方法,哪个效率更高
    展开

    作者回复: 对于这种请求,我更喜欢 # 操作符,table_nkeys里面还是有不少判断逻辑的。性能我没有测试,应该是#更好一些。

  • Geek_41dcba
    2019-08-02
    感谢老师,让我对openresty有了比较全面的认识。但目前在写测试用例跑CI时,还是有一些无从下 1. 某一个用例对系统环境有要求,比喻依赖时间,我想要模拟在一天中某段时间执行代码其他时间不执行,或者响应内容中表示时间字段的内容精度要求很高,如何去验证这个精度(我现在都做法是like方式去正则匹配,这个字段的内容是根据当前时间生成,猜测一个大概的时间) 2. 如何模拟一个用户请求,出现多级的upstream(模拟多级缓存不存在是服务端发起uostream的场景)
    展开

    作者回复: 第一个问题,你的做法是正确的,在 OpenResty 中也是用正则来判断时间的。你可以看下 lua-nginx-module 中 012-now.t 这个测试案例的做法; 第二个,上游都是可以在测试案例中模拟出来的,比如:https://github.com/iresty/apisix/blob/master/t/APISix.pm#L79