裸写http.get压测失败是因为在测本机ulimit和tcp栈而非服务,每次请求新建连接导致time_wait耗尽端口、dns查询毛刺、tls握手cpu瓶颈;k6需用constant-vus/ramping-vus模式、禁用连接复用、关注p95/p99延迟。

为什么裸写http.Get压测 Golang 接口会失败
因为这不是在测服务,是在测你本机的 ulimit 和 TCP 栈。每次调用 http.Get 都新建一个 http.Client,而默认 Transport.MaxIdleConns = 0,等效于每请求建新连接:
-
TIME_WAIT连接数几秒内耗尽本地端口,报too many open files - 反复 DNS 查询引发延迟毛刺,尤其在压测域名时更明显
- HTTPS 请求频繁 TLS 握手,
go tool pprof一看 CPU 时间全卡在crypto/tls - 错误如
dial tcp: lookup xxx: no such host不是服务挂了,是本地解析器被冲垮
k6 中怎么配出真实并发而非“伪并发”
k6 的 vus(虚拟用户)不是线程,而是独立 JS 执行上下文;用 for + go 不仅无效,还会破坏调度逻辑:
- 测稳定吞吐量:用
constant-vus,例如k6 run --vus 200 --duration 2m script.js - 找系统拐点:用
ramping-vus,比如--stage 30s:50,1m:200,30s:50 - 防脉冲流量:别写
sleep(1),改用per-vu-iterations+exec控制单 VU 行为 - 禁用连接复用暴露真实瓶颈:加请求头
{ 'Connection': 'close' };HTTP/2 则需http.setHTTP2(false)
看什么指标才反映真实用户体验
http_req_duration 的 mean 值基本没用,它被大量快响应拉低,掩盖长尾问题:
- P95/P99 延迟决定用户是否感知卡顿,必须提取——跑时加
--out json=output.json,再用jq '.metrics.http_req_duration.values.p95' - 脚本内可定义自定义指标配合
check(),例如:check(res, { 'p95 latency duration - 错误率要和延迟联动看:
http_req_failed突增但http_req_duration.p99未涨?大概率是服务主动限流或熔断
本地跑 k6 压测 Golang 微服务最容易翻车的细节
真正难的从来不是写脚本,而是让每一次请求都逼近生产流量的真实路径:
- 发压机和被测服务不能共用一台机器,否则 CPU、网络栈、文件描述符全争抢
- Golang 服务要开
pprof(如http.ListenAndServe("localhost:6060", nil)),压测中实时抓goroutine/heapprofile -
k6默认启用 HTTP/2,但 Nginx 等反向代理若未开启h2,会静默降级失败,需确认或显式关掉 - 测试域名务必走真实 DNS,别写
127.0.0.1——否则绕过 DNS 缓存和 TLS SNI,测的不是线上链路
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











