当你的接口变慢了、部署新环境了、或者被客户投诉"服务器卡",你拿什么数据来说话?"凭感觉"在性能问题面前一文不值。本文从网络延迟到应用吞吐,从一条命令到可复现的压测脚本,讲清如何科学地测出服务器的"快"与"慢"。
一、先搞清楚:你在测哪一层的快慢?
"服务器快慢"是个笼统的说法,先拆清楚,否则工具选错,测出来的结论毫无意义。
| 层次 | 衡量指标 | 典型工具 |
|---|---|---|
| 网络链路 | RTT 延迟、丢包率、带宽 | ping、mtr、iperf |
| 传输层 | TCP 握手耗时、端口连通性 | tcping、nc |
| DNS 解析 | 解析耗时、TTL | dig、nslookup |
| 应用层 | 响应时间、吞吐量、并发 | curl、ab、wrk、JMeter |
| 数据库/后端 | TPS、QPS、慢查询 | 各框架内置监控 |
一句话结论:先确定瓶颈在哪一层,再选工具。 如果用户说"打开网页很慢",可能是 DNS 解析慢、可能是 CDN 回源慢、也可能是后端 SQL 慢------三者的排查工具完全不同。
二、最基础的三大命令:手边随时能用
1. ping ------ 看网络延迟与丢包
bash
ping -c 10 example.com
重点关注两个数字:
- 平均延迟(avg RTT):本地到服务器单程往返的基准。同城机房间一般 <10ms,跨省约 30~60ms,跨境 100ms+。
- 丢包率:只要出现丢包,就说明链路不稳定,延迟再低也没用。
ping 测的是 ICMP 协议,注意:很多云厂商的防火墙会丢弃 ICMP 包,ping 不通不代表服务器挂了,需要用下面两个工具交叉验证。
2. curl ------ 看 HTTP 各阶段耗时
这是排查 Web 应用慢的头号工具,一定要会用:
bash
curl -o /dev/null -s -w \
'DNS: %{time_namelookup}s\nTCP连接: %{time_connect}s\nTLS握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\n' \
https://example.com/api/health
输出示例:
DNS: 0.021s
TCP连接: 0.045s
TLS握手: 0.128s
首字节: 0.452s
总耗时: 0.631s
分阶段定位技巧:
- DNS 耗时高 → 本地 DNS 或公共 DNS 问题
- TCP 连接高 → 网络链路问题
- TLS 握手高 → 证书链过长或 SSL 卸载配置问题
- 首字节高但总耗时正常 → 服务端处理慢,是后端代码/数据库的锅
- 首字节快但总耗时高 → 响应体过大,传输瓶颈
3. 多测几次,别信单次结果
网络有抖动,单次结果没意义。用循环取统计值:
bash
for i in {1..10}; do
curl -o /dev/null -s -w '%{time_total}\n' https://example.com/
done | sort -n | awk '{a[NR]=$1} END {print "min:", a[1], "| p50:", a[int(NR*0.5)], "| p95:", a[int(NR*0.95)], "| max:", a[NR]}'
三、进阶压测:测"扛不扛得住"
上面测的是单请求快慢 ,但服务器慢往往表现为"人一多就慢"。这时候要上压测工具,测吞吐量和并发下的延迟。
1. ab(ApacheBench)------ 最轻量,够用
系统自带或一条命令安装,适合快速摸底:
bash
ab -n 10000 -c 100 https://example.com/api/test
关键看两个指标:
- Requests per second:吞吐量,每秒能处理多少请求
- Percentage of requests served within:百分位延迟,重点看 p95、p99
2. wrk ------ 更现代,压测利器
ab 是单线程模型,wrk 支持多线程多连接,压得更狠、数据更真实:
bash
wrk -t 8 -c 200 -d 30s http://example.com/api/test
注意 wrk 不支持 HTTP/2 ,压 HTTPS 站点时加 --http 或用下面的工具。
3. 企业级场景上 JMeter
需要复杂场景(登录态、参数关联、分布式压测、图形化报告)时,Apache JMeter 是标准答案。适合正式压测报告,不适合随手快速验证。
四、别忽略的两层:TCP 与带宽
很多"服务器慢"其实是网络带宽或 TCP 层的问题。
tcping ------ 测 TCP 端口连通与延迟
bash
tcping example.com 443
curl 测的是"完成 HTTP 请求",tcping 只测 TCP 握手,能排除应用层的干扰,单独看链路质量。
iperf3 ------ 测真实带宽
怀疑"带宽不够"时,用 iperf3 双端测:
bash
# 服务端
iperf3 -s
# 客户端
iperf3 -c server_ip -t 30 -P 4
实测带宽 vs 你购买的带宽规格,一对比就知道是不是带宽被跑满了。
五、给 Python 开发者的可复现测试脚本
作为 Python 开发者,命令行的坑在于不好批量、不好记录、不好自动化。给你一个可落地的脚本骨架,既能测单点延迟,也能做并发压测:
python
import time
import statistics
import concurrent.futures
import requests
URL = "https://example.com/api/health"
N = 200 # 总请求数
CONCURRENCY = 20 # 并发数
def one_request(_):
start = time.perf_counter()
try:
r = requests.get(URL, timeout=10)
return {"ok": True, "status": r.status_code, "latency": (time.perf_counter() - start) * 1000}
except Exception as e:
return {"ok": False, "err": str(e), "latency": (time.perf_counter() - start) * 1000}
with concurrent.futures.ThreadPoolExecutor(max_workers=CONCURRENCY) as ex:
results = list(ex.map(one_request, range(N)))
latencies = sorted(r["latency"] for r in results)
ok = sum(1 for r in results if r["ok"])
print(f"总请求: {N} 成功: {ok} 成功率: {ok / N:.1%}")
print(f"平均延迟: {statistics.mean(latencies):.1f}ms p50: {latencies[int(N*0.5)]:.1f}ms "
f"p95: {latencies[int(N*0.95)]:.1f}ms p99: {latencies[int(N*0.99)]:.1f}ms")
要点:
- 用线程池模拟并发,比串行 for 循环真实得多
- p95/p99 比平均值更重要------平均值好看但尾部延迟高,用户体验照样差
- 把脚本参数化(URL、并发数、次数),沉淀成团队可复用的测试工具
六、避坑指南:常见的测试误区
- 在服务器本机测自己 :curl 本机 localhost 走的是回环口,延迟近乎为 0,测不出真实链路问题。要在客户端视角(用户所在网络)测。
- 只测一次:抖动是常态,至少测 5~10 次看分布,而不是看单次。
- 只看平均值:服务器慢往往体现在 p99 上,平均值会被少数快请求拉低。
- 压测打爆生产:压测会真实消耗服务器资源,先小并发摸底,再逐步加大,别一上来 1000 并发。
- 忽略 DNS:很多人测"网站慢"跳过了 DNS 阶段,结果换 DNS 就能解决。
- 用错误的工具测错误的层:ping 不通就断定服务器挂了(可能被防火墙拦 ICMP);curl 慢就怪网络(可能其实是后端代码慢)。
七、一句话总结
测快慢的本质,是把"慢"定位到具体某一层------DNS / TCP / TLS / 应用 / 数据库。先用 curl 分阶段定位,再用 ping、tcping 排除网络层,最后用 wrk 或脚本做并发压测拿 p95/p99。指标比感觉可靠,脚本比命令可复现。
如果你的问题恰好是"服务器慢",按这个顺序走一遍,基本能在十分钟内找到瓶颈所在。