反向代理后的端口数量限制

2024 年 11 月 11 日
 zhouhuab

WS 服务放在 NGINX 后面,根据 4 元组原理( localhost + [1-2**16), localhost+<listen port>),后端一个 listen 端口支持的最大活跃连接数目就是可用端口总数,大家是怎么突破这个限制(在只有一台服务器的前提下),多加一些 listen 端口,还是说规避反向代理?一些负载均衡服务是不是也有同样的问题?假设后端是 MQTT 服务,活跃连接很多,虽然消息频率很低

4321 次点击
所在节点    程序员
35 条回复
ShuA1
2024 年 11 月 11 日
在单台服务器的情况下,要突破单个后端 listen 端口支持的最大活跃连接数(约为可用端口总数),可以考虑以下几种策略:

1. 增加多个 listen 端口:
增加多个后端端口监听,利用 Nginx 或其他负载均衡工具将请求分散到多个端口,从而提升整体可支持的连接数。每个端口理论上可以使用约 6 万多个源端口,这样可以突破单端口的限制。

2. 使用 IP 地址别名( IP Aliasing ):
给服务器配置多个本地 IP 地址(例如 127.0.0.1, 127.0.0.2 等),每个 IP 地址都可以支持一组源端口,配合不同的 listen 端口可以进一步提升总连接数。

3. 开启内核参数调整:
在 Linux 内核参数中调整 net.ipv4.ip_local_port_range ,增大系统可用的源端口范围,并配合 net.ipv4.tcp_tw_reuse 和 tcp_tw_recycle (在合适场景下)减少 TIME_WAIT 端口占用时间。但要注意,这些参数调整可能带来安全和连接稳定性风险。

4. 采用 WebSocket 长连接优化:
对于 MQTT 协议,可以使用 WebSocket 长连接( Nginx 支持 WebSocket 代理),这样只用占用一次 TCP 连接即可实现长时间的低频消息传输,适合高活跃但低频的场景。

5. 考虑负载均衡服务的方案:
确实,大部分负载均衡服务也会遇到同样的问题。可以选择支持 四层负载均衡( TCP 直通) 的产品,这类负载均衡可以分散连接到不同 IP 或端口,并能够优化多 TCP 连接处理的效率。此外,负载均衡产品通常会用 SO_REUSEPORT 来实现多端口监听和多进程并发,这样可以增加连接数。

6. TCP Multiplexing 或 HTTP/2, HTTP/3 复用(视协议支持情况):
如果协议允许,可以考虑 HTTP/2 或 HTTP/3 的多路复用特性,通过复用单个 TCP 连接实现多个请求,这样可以减少活跃连接数的需求。

在高活跃 MQTT 服务的场景下,推荐通过 增加 listen 端口 和 多个本地 IP 组合,配合 内核参数优化 来实现较高的并发连接支持。这些措施有助于在单台服务器上突破连接限制,同时保持连接的低频消息传输。
cctv6
2024 年 11 月 11 日
一个接口可以设置多个 ip 。不仅后端服务器可以设置多个 ip ,负载均衡服务器向后端发起连接的时候,负载均衡也是可以配置多个 ip 的。
zhouhuab
2024 年 11 月 11 日
@ShuA1 有点像 AI 回答,:(
urlk
2024 年 11 月 11 日
1. 取消代理 直连后端

2. 通过域名 DNS 轮询,配置到不同服务器上

3. 后端出一个接口, 返回可用的服务器地址列表, 前端再进行长连接 或者 302 到对应服务器 这种做法自由度最高, 可以自定义分配策略
salmon5
2024 年 11 月 11 日
https://github.com/XianwuLin/xianwulin.github.com/issues/26
https://www.iamle.com/archives/1865.html

但是一般不用过多考虑,60000 个连接,1 个服务器首先是网卡带宽和 nginx 达到瓶颈,横向增加 nginx 就行了。
daimaosix
2024 年 11 月 11 日
@zhouhuab 不是像,就是
opengps
2024 年 11 月 11 日
这个数字虽然存在,但几乎用不上,你什么样的业务能用光 6 万个端口?
Leon6868
2024 年 11 月 11 日
@ShuA1 #1

@Livid LLM 回复
zhouhuab
2024 年 11 月 11 日
@opengps MQTT 上挂着百万个设备
nevermoreluo
2024 年 11 月 11 日
我大概明白你想要什么了,让我想起十几年前那个公司在用 LVS 可能可以解决你的困境,但也只是可能,毕竟 lvs 是另一个火坑。
我感觉现实点是直接放出 mqtt 后端,这个路最快。
抛开现实业务是否真的需要这么多连接,就这个问题而言,我觉得这个 nginx 反代的 6w 上限确实阻碍了你,这一点上不论换 haproxy 还是 squid 都一样。
nevermoreluo
2024 年 11 月 11 日
winglight2016
2024 年 11 月 11 日
mqtt 上挂百万个设备,我的理解是,查询/更新设备状态,这个思路换成设备上报状态到平台,然后通过平台查询就可以解决——移动这些运营商也是这种方案。

另外,使用 mobus 这种串口协议也可以,只要板子上的寄存器够大,多少设备都能接进来。
zhouhuab
2024 年 11 月 11 日
@nevermoreluo UDP 的坑更大,很多 host 都跑不好 UDP
nevermoreluo
2024 年 11 月 11 日
@zhouhuab 那我下班了, 信息有限,只能当个狗头军师。祝你好运吧
opengps
2024 年 11 月 11 日
@zhouhuab 你这场景我想说,如果不是硬件锁死就不太适合用 mqtt 了。还不如回归原始 tcp 一个端口承载几万,百万设备那也无非是百个端口的压力
thebszk
2024 年 11 月 11 日
@zhouhuab 很怀疑是硬杠,如果设备量百万,不应该用单台服务器负责,可以考虑是 dns 分流到多台服务器。
cnuser002
2024 年 11 月 11 日
你是前端想通过 Websocket 连到 MQTT 服务器上收消息么?通过反向代理转一下?

要是指 MQTT 服务器怎么做单机并发的话,你可以参考 EMQX 是怎么做的。
pursuer
2024 年 11 月 11 日
有的反代可能支持使用 Unix Domain Socket 或 Windows Named Pipe ,虽然我觉得最好的方案还是服务都能支持一个连接复用的网关模型。
mytsing520
2024 年 11 月 11 日
横向扩容加机器,反正不要把一台机器容量用到死就行
hackroad
2024 年 11 月 11 日
服务器同时能够承受的并发数是由带宽、硬件、程序设计等多方面因素决定的,你想问的如何在在 linux 下 从 c10k 到 c1000k ,不如设计合理的高可用架构,微信这么大的体量不可能是单一架构实现高可用。

比如说分区域负载
智能 dns 调度
所有区域根据负载动态下发网关
client 拿配置多链路
ip 保底链路
https dns
如何避免木桶效应

从你问的来看,方向就错了。就算你的机器内存 TB 级别,网卡中断、链路可用性、带宽等各方面满足你 c1000k c10000k ,你就不怕挂了影响全局。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/1088368

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX