V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhouhuab
V2EX  ›  程序员

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

  •  
  •   zhouhuab · 17 天前 · 2836 次点击

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

    35 条回复    2024-11-16 11:20:05 +08:00
    ShuA1
        1
    ShuA1  
       17 天前   ❤️ 1
    在单台服务器的情况下,要突破单个后端 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
        2
    cdlnls  
       17 天前 via Android
    一个接口可以设置多个 ip 。不仅后端服务器可以设置多个 ip ,负载均衡服务器向后端发起连接的时候,负载均衡也是可以配置多个 ip 的。
    zhouhuab
        3
    zhouhuab  
    OP
       17 天前
    @ShuA1 有点像 AI 回答,:(
    shenjinpeng
        4
    shenjinpeng  
       17 天前
    1. 取消代理 直连后端

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

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

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

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

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

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

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

    从你问的来看,方向就错了。就算你的机器内存 TB 级别,网卡中断、链路可用性、带宽等各方面满足你 c1000k c10000k ,你就不怕挂了影响全局。
    sujin190
        21
    sujin190  
       17 天前 via Android
    @zhouhuab 都这设备数量级了,还用啥 7 层代理吧,4 层都用不起,直接 dns 均衡足够了,否则太浪费资源了,且不说内存使用量大增加了不少,光是心跳就要增加不小的 cpu 使用率了,而且还要考虑重启更新或者网络中断啥的集中重连需要预留资源的消耗也更多,也就是如果你平时就内存 cpu 带宽全满那重启就有可能没有足够资源起得来了
    zhouhuab
        22
    zhouhuab  
    OP
       17 天前
    @sujin190 还不是为了省钱,设备是多,可都是白嫖,就图个引流,所以尽量减少投入。我们现在用的是 UDP ,跑在 16core/32G 的服务器上,每月 30T 的 UDP 流量(心跳服务),目前相当拥挤。
    Livid
        23
    Livid  
    MOD
       17 天前
    @Leon6868 谢谢,那个用 AI 回复的账号已经被彻底 ban 。
    sujin190
        24
    sujin190  
       16 天前 via Android
    @zhouhuab 那就更不要 7 层代理了,按理说心跳至少可以到 2 分钟,微信之前还发过文研究过 4 到 5 分钟也撑得住,估计给个 3 分钟估计可以,ws 的心跳包好像只有 3 字节吧,算上 ip tcp 头,100 万设备全天在线一个月估计也就 1T 多流量,你这咋高这么多。。
    zhouhuab
        25
    zhouhuab  
    OP
       16 天前
    @sujin190 现在是 UDP ,NAT 端口也就预留 30 秒左右,所以不可能用分钟心跳给 UDP
    soul11201
        26
    soul11201  
       15 天前
    连接池
    humbass
        27
    humbass  
       15 天前
    太 TM 扯了,当年阿里云牛逼的工程师一个挂载点最多 10 万个 MQTT 客户端,还是 TCP 形式的,WS 占资源更多,顶多 50000 万个。做到百万这个份上,是不是客户端要优化下,连接之前轮询下当前可用服务器,然后再连接对应的挂载点
    zhouhuab
        28
    zhouhuab  
    OP
       15 天前
    很好奇,emqx 的集群是怎么做的
    zhouhuab
        29
    zhouhuab  
    OP
       14 天前
    @sujin190 可以联系你,聊聊吗?
    sujin190
        30
    sujin190  
       14 天前 via Android
    @zhouhuab MTM2OTAzOTcyMA== 可以加 q
    zhouhuab
        31
    zhouhuab  
    OP
       14 天前
    @sujin190 我给你发推吧,我老了,不再用 q 了,:)
    zhouhuab
        32
    zhouhuab  
    OP
       14 天前
    @zhouhuab 看到你邮件了,我给你发邮件
    zhouhuab
        33
    zhouhuab  
    OP
       14 天前
    @sujin190 看到你邮件了,我给你发邮件
    Shir0k0
        34
    Shir0k0  
       12 天前
    @humbass 50000 万个?五万万个?
    humbass
        35
    humbass  
       12 天前
    @Shir0k0 明显是写错了啊,5 万
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3131 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 13:55 · PVG 21:55 · LAX 05:55 · JFK 08:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.