MaxIdleConns是全局空闲连接总数上限,MaxIdleConnsPerHost是单host最大空闲连接数,后者不能超过前者;若只调大后者而忽略前者,多host会争抢导致部分域名无法复用连接,合理协同配置才能提升复用效率。
maxidleconns 不是并发上限,设太大反而会拖慢连接复用效率,必须和 maxidleconnsperhost、目标服务分布协同调整。
MaxIdleConns 和 MaxIdleConnsPerHost 的关系容易搞反
这两个参数不是独立生效的:MaxIdleConns 是全局空闲连接总数上限,MaxIdleConnsPerHost 是单个 host(比如 api.example.com:443)最多能缓存的空闲连接数。但后者不能超过前者——如果 MaxIdleConns 设为 100,MaxIdleConnsPerHost 却设成 200,实际生效的仍是 100。
常见错误是只调大 MaxIdleConnsPerHost,却忘了同步放大 MaxIdleConns,结果多个 host 抢同一个池子,某些域名始终拿不到空闲连接。
- 只调一个后端服务?
MaxIdleConns可设为 0(不限制),重点调MaxIdleConnsPerHost - 同时调 20+ 个不同域名?
MaxIdleConns至少设为MaxIdleConnsPerHost × 3,留出余量 - 默认值 100 在多数微服务场景下偏小,压测时容易看到大量
net/http: request canceled (Client.Timeout exceeded while awaiting headers)
设太高会导致失效连接滞留、内存浪费甚至服务端拒绝
连接池不是越大越好。MaxIdleConns 过大会让已断开或服务端已回收的连接在客户端池里“装死”更久,尤其当下游 LB 切换 IP 或服务重启后,这些连接仍被复用,直接返回 i/o timeout 或空响应。
- 单机 QPS MaxIdleConns = 200 足够
- QPS 200+ 且目标分散?建议
MaxIdleConns = 500,再配合监控看http.Transport.IdleConnMetrics中的 rejected 连接数 - 设到 1000+ 且没配套健康检查?大概率会观察到 TIME_WAIT 暴涨 + 随机超时,不是连接没复用,而是复用了坏连接
不共享 Client 实例时,MaxIdleConns 完全无效
MaxIdleConns 是 http.Transport 的字段,而 Transport 必须被多个请求共用才能体现池的效果。如果每次请求都 &http.Client{Transport: &http.Transport{...}},等于每个 Client 各自建了个迷你池,参数再大也没意义。
- 必须将
*http.Client作为包级变量或依赖注入单例使用 - 禁止在 HTTP handler 里 new Client,也禁止用
http.DefaultClient(它的 Transport 无法修改) - 多个业务逻辑需要不同超时?新建
http.Transport,再传给新http.Client;别复用 Transport 却改 Client.Timeout
真正难调的不是数值本身,而是确认连接到底有没有被复用——用 curl -v 看响应头有没有 Connection: keep-alive,再用 netstat -an | grep :443 | grep ESTABLISHED | wc -l 对比压测前后数量变化,比光看参数靠谱得多。


















