Fiber框架本身不提供连接级并发限制,需在net.Listener层用netutil.LimitListener包装实现硬性TCP连接数控制,位置必须在Accept()返回前,而非HTTP中间件或fasthttp.Server配置中。

Go 的 Fiber 框架本身不提供连接级并发限制能力——它基于 fasthttp,而 fasthttp.Server 也只暴露 Concurrency(单核协程调度上限)和 MaxRequestsPerConn(单连接请求数),**都不等于“每个客户端或全局最大 TCP 并发连接数”**。真要控连接数,必须在 net.Listener 层动手。
用 netutil.LimitListener 包装 Listener 最直接
golang.org/x/net/netutil.LimitListener 是标准方案,它在 Accept() 返回前做计数拦截,位置正确、无竞态、不依赖 HTTP 层逻辑。
- 它只限制新连接接入,不影响已建立连接的请求处理
- 必须在
fiber.App.Listen()之前包装原始 listener,不能等 server 启动后再设 - 传入的
max是硬上限,超限时系统直接返回EMFILE或ECONNREFUSED,客户端表现为连接失败 - 示例:
lis, _ := net.Listen("tcp", ":3000") limitedLis := netutil.LimitListener(lis, 1000) app.Listener(limitedLis)
自定义 Listener 包装器支持 IP 级连接数限制
若需按客户端 IP 限连接(比如单 IP 最多 5 个并发 TCP 连接),netutil.LimitListener 不够用,得自己封装:
- 核心是维护一个
sync.Map,key 为提取出的真实 IP(注意从X-Forwarded-For解析并校验可信代理),value 为当前连接数 - 在
Accept()返回后立即检查并递增;调用conn.Close()时递减(需用net.Conn的SetDeadline或context触发清理) - 别在
Accept()内做 DNS 解析或网络请求,否则会阻塞整个 listener - IP 提取必须防伪造:只信任 Nginx/HAProxy 等配置的固定代理 IP 段,否则
X-Forwarded-For可被客户端随意篡改
别踩这些坑
很多人误以为以下方式能控连接数,实际无效:
- 在
fiber.App.Use()中用sync.WaitGroup或全局计数器增减——这只能统计「正在执行的 HTTP 请求」,TCP 连接早已建立,限制失效 - 靠
fasthttp.Server.Concurrency设低值——这只是限制单线程内同时处理的请求数,跟连接数无关;设成 1 不代表只能有 1 个连接 - 用
fiber.RateLimit中间件——它只限制 QPS,对长连接、WebSocket、大文件下载完全不起作用 - 在
net.Conn的Read()或Write()阶段才检查——此时连接已就绪,资源(FD、内存)已被分配,属于事后补救
真正关键的是:**连接数限制必须发生在 Accept() 成功之后、交付给 fasthttp 处理之前**。这个窗口期极短,但只有在这里插手,才能确保不漏掉任何连接,也不误杀合法流量。其他所有“看起来像限流”的做法,基本都只是在限请求,不是限连接。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










