fiber 默认的 fasthttp.client 不适合长期做反向代理,因其禁用连接池(maxidleconnduration=0),导致每次请求新建 tcp 连接、无法复用 keep-alive、time_wait 暴增;且不支持流式透传、错误状态码透传、多上游隔离及健康检查等关键能力。

直接用 Fiber 做反向代理网关可行,但默认不支持上游连接复用、超时控制和错误透传,硬上容易在线上出 502 或连接泄漏。
为什么 Fiber 默认的 fasthttp.Client 不适合长期做反向代理
Fiber 内部用 fasthttp.Client 实现 c.Send 或 c.Redirect 类操作,但它默认禁用连接池(MaxIdleConnDuration=0),每次请求都新建 TCP 连接;上游服务若启用了 keep-alive,这里却无法复用,导致 TIME_WAIT 暴增、延迟升高。
- 必须显式配置
Client并启用连接池:client := &fasthttp.Client{ MaxIdleConnDuration: 30 * time.Second, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } - 不能直接用
c.Send转发原始 body ——fasthttp的RequestCtx不暴露底层net.Conn,无法做流式透传,大文件或长连接会卡死 - 上游返回非 2xx 状态码时,
Fiber默认不透传响应头(如Content-Type、Set-Cookie),需手动拷贝
用 fasthttp.HostClient 替代全局 fasthttp.Client 管理上游
如果网关要对接多个后端(比如 api.example.com 和 auth.example.com),用单个 fasthttp.Client 会混用连接池,可能引发 Host 头错乱或 TLS SNI 冲突。更稳妥的是为每个上游域名配一个 fasthttp.HostClient:
-
HostClient自动处理Host头、SNI 和连接隔离,避免跨服务污染 - 设置
DisableKeepAlive: false(默认就是 false,但显式写出来防误) - 注意
Addr字段必须不含协议,只填"api.example.com:443",否则会解析失败 - 示例初始化:
authClient := &fasthttp.HostClient{ Addr: "auth.example.com:443", MaxIdleConnDuration: 30 * time.Second, TLSConfig: tlsConfig, // 若用自签名证书需定制 }
手动透传请求/响应,绕过 Fiber 中间件干扰
别用 c.Status(502).SendString(...) 或 c.JSON 处理上游错误 —— 这会覆盖原始响应体和 header。正确做法是用 ctx.Request().URI().SetPath(...) 改写路径后,直接调用 hostClient.Do,再逐项拷贝:
- 先清空当前 ctx 的 response:
ctx.Response.Reset()
- 拷贝状态码:
ctx.Response.SetStatusCode(resp.StatusCode)
- 遍历并拷贝 header(跳过
Connection、Transfer-Encoding等 hop-by-hop 字段):resp.Header.VisitAll(func(key, value []byte) { if string(key) == "Connection" || string(key) == "Transfer-Encoding" { return } ctx.Response.Header.SetCanonical(key, value) }) - 用
ctx.Response.SetBodyStream流式转发 body,避免内存暴涨:ctx.Response.SetBodyStream(resp.Body, -1)
健康检查与上游切换需要自己补全
Fiber 没有内置 upstream health check 或 failover 逻辑。如果你依赖多个实例做容灾,得自己实现:
- 定期用
hostClient.DoHead探活,失败时标记该实例为 down,并维护一个可用列表 - 轮询或随机选上游时,跳过 down 状态节点;连续失败超过阈值(如 3 次)才触发熔断
- 注意:
fasthttp的 timeout 是 per-request 的,不是连接池级的,所以探活请求也得设独立 timeout - 别依赖
net/http的http.Transport健康机制 ——fasthttp完全不兼容它
真正难的不是转发本身,而是连接生命周期管理、header 语义还原和故障传播收敛 —— 这些细节不抠清楚,压测时连接数飙升或偶发 502 就很难定位。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











