指定域名的IP地址
最近在用 artillery 做压测时遇到一个问题。我需要压测某一个通过域名访问的服务,而这个域名背后的机器地址需要随着压测用例变化的。通常这就是DNS要做的事情 - 把不变的域名和变化的地址关联起来 - 但我又没权限控制这个域名的解析地址。
另一个选择是跑到压测客户端的机器上,修改 /etc/hosts
让它指向不同的地址。不过压测客户端可不止一个,即使有办法批量下发 /etc/hosts
到每台机器上,事后我还需要把 /etc/hosts
给恢复回去,不然后面的人难免会踩坑。
还有一种选择,就是在客户端压测代码里根据不同的用例指定域名对应的IP。比如 curl 就有个 --resolve
参数可以指定域名和IP的对应关系,wrk 也可以通过 Lua 脚本设置。问题在于 artillery 并不支持这样的特性。
正在我一筹莫展之际,一个想法从脑海中蹦出来。我可以用 docker 封一层 artillery,然后通过 docker-compose 的 extra_hosts
配置设置映射关系。
version: '3'
services:
benchmark:
image: artillery:v1.6.0 # 我自己打了个 artillery v1.6.0 的镜像
network_mode: "host"
extra_hosts:
# 映射关系在这里!
- xxx.com:$XXX_HOST
volumes:
- .:/artillery
command: artillery run xxx.yml
注意我这里使用了 $XXX_HOST
而不是直接在文件里写死 IP 地址。这样一来就能通过 docker-compose 的变量机制,在执行 docker-compose up
的时候通过环境变量注入真正的 IP 地址。就像这样:
$ XXX_HOST=192.168.0.123 docker-compose up
这下我只要根据测试用例的不同修改具体的命令行的值,就可以实现类似于 curl 的 --resolve
功能。
extra_hosts
的原理很简单,就是把配置文件里指定的映射关系写到容器的 /etc/hosts
文件,所以即使是 network_mode: "host"
下也能用。
指定 DNS
同样地,通过
dns:
- 8.8.8.8
也能把 DNS 服务器地址写入到容器的 /etc/resolv.conf
文件,来自定义客户端用的DNS服务器。
利用多核
压测的过程中我们还发现一个问题:作为一个 node.js 应用,artillery 仅支持单核,而只跑一个 artillery 没办法充分利用客户端机器的性能。artillery 2.0 计划通过起多个worker的方式来用多个CPU,但远水解不了近渴,当前最新版本的 artillery 还不支持这一特性。好在我们已经套上了一个 docker 的壳,大可以通过 docker-compose 的方式起多个实例:
docker-compose up --scale benchmark=N
想一次性起多少个实例,就指定 N 为多少。当然这么做最后压测的结果需要自己计算各个实例的结果的总和。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。