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

41 天前
 zhouhuab

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

3050 次点击
所在节点    程序员
35 条回复
ShuA1
40 天前
在单台服务器的情况下,要突破单个后端 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 组合,配合 内核参数优化 来实现较高的并发连接支持。这些措施有助于在单台服务器上突破连接限制,同时保持连接的低频消息传输。
cdlnls
40 天前
一个接口可以设置多个 ip 。不仅后端服务器可以设置多个 ip ,负载均衡服务器向后端发起连接的时候,负载均衡也是可以配置多个 ip 的。
zhouhuab
40 天前
@ShuA1 有点像 AI 回答,:(
shenjinpeng
40 天前
1. 取消代理 直连后端

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

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

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

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

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

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

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

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

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

https://www.v2ex.com/t/1088368

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

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

© 2021 V2EX