评估一台云服务器的Web处理能力,最直接的方式就是做压力测试。wrk是一款基于事件驱动模型的开源HTTP基准测试工具,单机即可产生数万甚至数十万的并发连接,而自身资源占用极低,非常适合用来对阿里云ECS实例进行Web性能评测。本文将从环境准备、wrk使用、Lua脚本进阶、结果解读四个层面,完整演示一套可复现的压测流程。

一、压测前的环境准备与压测端规划
一次有意义的压测,首先要保证压测端不会成为瓶颈。wrk虽然高效,但如果在一台1核1G的小机器上疯狂打流量,得到的数据更多反映的是压测机本身的极限,而不是被测服务器的性能。因此在规划时,建议压测端使用与被测ECS同规格或更高规格的实例,并尽量让两台机器处于同一个地域和可用区(或者使用内网地址通信),避免公网带宽成为干扰因素。
阿里云ECS的安全组配置也容易被忽略。压测前需要确认安全组已放行压测机访问Web服务的端口(如80或8080),否则wrk会报大量连接超时,得出的数据毫无意义。同时建议关闭被测服务器上的无关服务,保持测试环境干净。
在系统层面,压测端和被测端都建议调整文件描述符上限,否则高并发时会报出too many open files错误:
# 临时调大文件描述符限制 ulimit -n 65535 # 查看当前限制 ulimit -n # 永久生效,修改 /etc/security/limits.conf # * soft nofile 65535 # * hard nofile 65535
如果是Linux内核较新的系统,默认的TCP参数一般够用;若压测连接数超过数万,可适当调整net.ipv4.ip_local_port_range扩大压测端的源端口范围,避免端口耗尽。
二、wrk的安装与基础用法
wrk使用C语言编写,依赖较少,在大多数Linux发行版上通过包管理器即可安装,例如CentOS的EPEL源或Ubuntu的apt install wrk。如果想使用最新版本,也可以从源码编译:
# 安装编译依赖 yum install -y git gcc make openssl-devel # 克隆并编译 git clone https://github.com/wg/wrk.git cd wrk make # 编译完成后得到可执行文件,复制到系统路径 cp wrk /usr/local/bin/ wrk --version
wrk的核心参数只有几个,理解它们是正确压测的前提:-t指定线程数,-c指定并发连接数,-d指定测试持续时间(如60s),-T指定请求超时时间,-H可添加自定义请求头。一个典型的基础压测命令如下:
# 2个线程,1000个并发连接,持续压测60秒 wrk -t2 -c1000 -d60s --timeout 30s http://192.168.0.10:80/
这里有一个经验法则:线程数一般设为CPU核心数的1到2倍即可,线程数设置过多反而会增加上下文切换开销。并发连接数才是真正控制压力大小的参数。wrk的每个连接默认启用HTTP长连接复用,这更接近现代浏览器和CDN回源的真实行为,如果想模拟短连接场景,可以在Lua脚本中主动关闭连接。
三、使用Lua脚本定制复杂压测场景
纯GET压测只能评估最简单的静态能力,实际业务往往需要携带参数、修改路径或进行身份认证。wrk通过Lua脚本提供了强大的定制能力,脚本中可以定义setup、init、request、response、done等多个阶段的回调函数。
例如下面的脚本为每个请求动态生成不同的URL路径和随机参数,用于测试后端路由和数据库查询性能:
-- custom_request.lua
-- 每次请求前被调用,构造本次请求
request = function()
local id = math.random(1, 100000)
local path = "/api/user/" .. id .. "/profile"
return wrk.format("GET", path, {["Content-Type"] = "application/json"})
end
-- 响应回调,可统计特定状态码数量
response = function(status, headers, body)
if status ~= 200 then
errors = (errors or 0) + 1
end
end
-- 压测结束时输出统计
done = function(summary, latency, requests)
io.write("非200状态码数量: ", (errors or 0), "\n")
end执行时通过-s参数加载脚本:
wrk -t4 -c2000 -d120s -s custom_request.lua --latency http://192.168.0.10:80/
需要注意,Lua中的math.random如果不设置随机种子,每次生成的序列相同,可能造成缓存命中偏高。可以在init函数中调用math.randomseed(os.time())来避免。另外,如果被测接口需要先登录获取Token,可以利用setup和线程级别的init函数在压测前完成认证,把Token存入线程局部变量。
四、压测结果解读与性能分析
wrk输出中最重要的三个指标是:吞吐量(Requests/sec)、延迟分布(Latency)和传输速率(Transfer/sec)。加上--latency参数后,wrk会输出详细的延迟分布,包括50%、75%、90%、99%分位数。评估Web性能时,平均延迟往往具有欺骗性,一个99%分位延迟达到数秒的系统,即使平均值很低,用户体验也会明显受损,因为总有部分用户落在长尾区间。
解读数据时要重点关注几个信号:如果吞吐量上不去同时CPU未跑满,通常是连接数设置不足或网络受限;如果被测ECS的CPU已接近100%而延迟飙升,说明已达到服务器处理极限;如果出现大量non-2xx响应或socket错误,需要检查后端应用是否有连接池耗尽、数据库超时等问题。对于阿里云ECS,还应注意实例规格的网络带宽上限,突发性能实例(t5、t6等)在CPU积分耗尽后性能会被限制,压测数据会出现明显抖动。
一次规范的评测应当固定多个压力梯度,逐步提升并发连接数(例如100、500、1000、2000、5000),每个梯度持续60秒以上,记录吞吐量和各分位延迟,绘制性能曲线找到系统的拐点。拐点之后再加压只会换来延迟的急剧上升,这个拐点才是被测ECS在当前Web架构下的真实容量上限。通过多次重复测试并对比数据,还可以验证Nginx参数调优、PHP-FPM进程数、内核TCP缓冲区等优化措施是否真正生效,形成完整的压测、分析、优化、回归的闭环。