wrk是一款开源的HTTP基准测试工具,采用多线程加异步事件驱动的架构,单机就能产生极高的并发请求量,资源占用却很低。相比老牌的ab(Apache Bench),wrk能输出更细粒度的延迟分布数据;相比JMeter,它又轻量得多,不需要图形界面,一条命令就能跑起来。这篇文章以阿里云ECS为例,从安装、使用到结果解读,完整走一遍Web性能评测的流程。

一、在阿里云ECS上安装wrk
wrk的安装方式有好几种,最直接的是从源码编译。它依赖git和编译工具链,先确保系统里装了gcc和make。以CentOS和Ubuntu为例,安装依赖的命令略有差异,但整个过程不超过五分钟。
如果你的ECS是CentOS或Alibaba Cloud Linux,执行下面的命令即可完成安装:
yum install -y git gcc make git clone https://github.com/wg/wrk.git cd wrk make cp wrk /usr/local/bin/ wrk --version
如果是Ubuntu或Debian系统,把第一行换成apt-get install -y git gcc make即可。编译完成后,执行wrk --version能看到版本号就说明安装成功了。也可以用包管理器直接装,比如CentOS的EPEL源里就有wrk包,不过版本可能偏旧,建议还是源码编译,几分钟就能搞定。
有一点需要注意:wrk最好安装在一台单独的测试机上,而不是被测的ECS本身。压测工具本身会消耗CPU,如果wrk和Web服务跑在同一台机器上,测试结果会互相干扰,数据就不可信了。建议再开一台低配ECS专门跑wrk,或者用本地电脑通过公网压测(但要考虑带宽瓶颈)。
二、wrk常用参数详解
wrk的基本用法是wrk [选项] URL,最核心的三个参数是-t(线程数)、-c(并发连接数)和-d(测试时长)。一个典型的命令长这样:
wrk -t4 -c200 -d60s http://192.168.0.10/index.html
这条命令表示用4个线程维护200个并发连接,持续压测60秒。线程数一般设置为CPU核心数的1到2倍即可,设得太大没有意义,因为wrk每个线程内部是事件驱动的,一个线程就能处理成百上千个连接。并发连接数才是真正模拟用户量的参数,可以根据目标负载逐步调大。
除了基础参数,还有几个常用选项值得记住:
-s <脚本>:加载Lua脚本,用于自定义请求方法、请求头、请求体,或做更复杂的测试逻辑-H <头部>:直接添加HTTP请求头,比如-H "Authorization: Bearer xxx"--latency:输出更详细的延迟分布,包括P50、P75、P90、P99百分位数据--timeout <秒>:设置请求超时时间,超过该时间的请求记为超时
其中--latency强烈建议每次都加上,因为平均延迟往往会掩盖长尾问题,而P99延迟才是用户体验的真实写照。举个例子,平均延迟50毫秒看起来不错,但P99延迟冲到2秒,意味着每一百个用户里就有一个要等很久,这在线上是不可接受的。
如果压测的是动态接口或需要POST请求,就要借助Lua脚本了。下面是一个发送POST请求的脚本示例:
wrk.method = "POST"
wrk.body = '{"username":"test","page":1}'
wrk.headers["Content-Type"] = "application/json"
request = function()
return wrk.format(nil, nil, nil, wrk.body)
end保存为post.lua后,用wrk -t4 -c200 -d60s -s post.lua --latency http://目标地址/api/list执行即可。脚本里还可以在response回调中校验返回内容,统计错误码数量,玩法很多。
三、压测Nginx并解读结果
假设被测ECS上跑了一个Nginx,返回一个静态页面,我们用wrk -t4 -c500 -d60s --latency http://192.168.0.10/压测,输出大致如下:
Running 1m test @ http://192.168.0.10/
4 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 42.15ms 105.30ms 1.02s 90.33%
Req/Sec 3.21k 456.20 5.80k 88.50%
Latency Distribution
50% 18.32ms
75% 35.60ms
90% 85.41ms
99% 402.15ms
3852000 requests in 60.00s, 2.80GB read
Requests/sec: 64200.11
Transfer/sec: 47.80MB逐项解读这些数据:Requests/sec就是QPS,本例约6.4万,说明这台ECS每秒能处理6.4万个请求;Latency Distribution里的P50是18.32毫秒,即一半请求在18毫秒内完成,P99是402毫秒,长尾比较明显;Socket errors如果出现非零值(比如connect超时、read超时),说明服务器或网络已经到瓶颈了,数据需要重新分析。
读结果时有几个经验法则。第一,看QPS曲线是否平稳,如果压测过程中QPS先高后低,可能触发了限流或者资源耗尽。第二,压测期间同步在服务器上执行top和vmstat观察CPU、内存和上下文切换,确认瓶颈到底在哪一层。第三,别只跑一次,至少跑三轮取稳定值,前一轮的连接缓存、CPU温度都可能影响结果。
不同的ECS规格表现差异很大。一台2核2G的入门款ECS跑静态页面,Nginx通常能到几万QPS;换成16核的通用型实例,轻松突破几十万。如果发现QPS上不去但CPU没跑满,大概率是配置问题,比如Nginx的worker_processes没设置成CPU核心数,或者内核参数没调优。
四、压测前的调优与注意事项
在阿里云ECS上做高压测,有几件事必须提前处理,否则测出来的数据会有大量误差。首先是文件描述符限制,高并发下Nginx需要大量FD,编辑/etc/security/limits.conf,加入:
* soft nofile 65535 * hard nofile 65535
其次是内核参数,把连接跟踪表调大,开启TIME_WAIT复用,在/etc/sysctl.conf中添加:
net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_tw_reuse = 1
改完后执行sysctl -p生效。客户端跑wrk的机器同样要调这些参数,尤其是端口范围,连接数上万时端口耗尽是常见问题。
安全组也别忘了。wrk的大量短连接可能触发阿里云安全组的限速策略,或者被云盾误判为攻击流量。测试时最好把压测机IP加入白名单,或者走内网压测,避免公网带宽成为瓶颈。走公网时,哪怕ECS买了固定带宽,比如5Mbps,那QPS上限很快就被带宽卡住,测出来的其实是带宽性能而不是服务器性能。
最后强调一下压测的道德边界:只压测自己的服务器,对别人的站点发起压力测试属于违法行为。在自己的ECS上做实验,才能既安全又高效地摸清服务器的真实性能底牌。