NGINX:超过 65535 个连接限制

Posted

技术标签:

【中文标题】NGINX:超过 65535 个连接限制【英文标题】:NGINX : Exceeds 65535 connections limit 【发布时间】:2016-03-08 21:23:49 【问题描述】:

与 HTTP 不同,websocket 从 HTTP 升级后保持长连接。

即使操作系统调整为使用所有端口,总共仍然只有 65536 个端口。 nginx 有可能超过这个限制吗?

一个潜在的解决方案是SO_REUSEPORT,但它缺少文档——至少我没有找到除了下面这段

NGINX 1.9.1 版引入了一项新功能,可以使用 SO_REUSEPORT 套接字选项,在较新版本的 许多操作系统,包括 DragonFly BSD 和 Linux(内核 版本 3.9 及更高版本)。此套接字选项允许多个套接字 侦听相同的 IP 地址和端口组合。然后内核 负载平衡跨套接字的传入连接。

因此,NGINX 调用 accept 来接受入站连接。

accept() 系统调用与基于连接的套接字类型一起使用 (SOCK_STREAM,SOCK_SEQPACKET)。它提取第一个连接 请求侦听套接字的挂起连接队列, sockfd,创建一个新的连接套接字,并返回一个新文件 引用该套接字的描述符。新创建的套接字不是 处于聆听状态。原始套接字 sockfd 不受 这个电话。

新的套接字会消耗端口吗?如果是,如何超过 65535 连接限制?

【问题讨论】:

TCP 连接由四元组(src_addr, src_port, dst_addr, dst_port) 定义。如果客户端使用不同的 IP 地址和/或源端口,您可以将服务器连接到同一端口上的超过 65536 个客户端。示例:服务器 IP 是 0.0.0.1,侦听端口 80。所有 4 元组都可以是 (*, *, 0.0.0.1, 80)。只要没有相同的 4 元组,服务器就可以在端口 80 上拥有内存允许的尽可能多的连接。 谢谢,我将问题更新得更清楚了。那么accept创建的新socket不会消耗不同的端口? 不,它不会切换到使用不同的端口。 感谢您的接受,为您的问题 +1;我也可以得到一份答案吗? 【参考方案1】:

您收到的评论是正确的:

TCP 连接由 4 元组(src_addr、src_port、dst_addr、dst_port)定义。如果客户端使用不同的 IP 地址和/或源端口,您可以将服务器连接到同一端口上的超过 65536 个客户端。示例:服务器 IP 是 0.0.0.1,侦听端口 80。所有 4 元组都可以是 (*, *, 0.0.0.1, 80)。只要没有相同的 4 元组,服务器就可以在端口 80 上拥有内存允许的尽可能多的连接。 – Cornstalks 2015 年 12 月 4 日 2:36

但是,在评估是否会超出限制时,您还必须考虑到 nginx 不仅仅是一个服务器(具有ngx_connection.c#ngx_open_listening_sockets() 调用 socket(2)bind(2)listen(2) 系统调用接管80 之类的端口,然后在无限循环中调用accept(2)),但它也可能是上游服务器的客户端(根据需要调用socket(2)connect(2) 以连接到8080 等端口上的上游)。

请注意,虽然它的服务器上下文不可能用完 TCP 端口(因为服务器在其所有连接中都使用单个端口,例如端口 80),但客户端上的 TCP 端口会用完是一种真正的可能性,具体取决于配置。您还必须考虑,在客户端对连接执行close(2) 之后,state goes to TIME_WAIT 会持续大约 60 秒左右(以确保如果任何迟到的数据包确实通过,系统会知道如何处理它们)。

不过,话虽如此,请注意 the SO_REUSEPORT option 到 getsockopt(2),至少在 the sharding context presented in the referenced release notes and reuseport announcement of nginx 1.9.1 中,与 65535 困境完全无关——它只是在内核和在内核下运行的应用程序:

我在 36 核 AWS 实例上使用 4 个 NGINX 工作人员运行了 wrk 基准测试。为了消除网络效应,我在 localhost 上同时运行客户端和 NGINX,并让 NGINX 返回字符串 OK 而不是文件。我比较了三种 NGINX 配置:默认(相当于accept_mutex on)、accept_mutex off 和reuseport。如图所示,reuseport 将每秒请求数提高了 2 到 3 倍,同时降低了延迟和延迟的标准差。

至于您的基本问题,解决传出TCP ports 问题的uint16_t 问题可能是在担心这一点时不通过TCP 使用后端,和/或通过proxy_bind 等使用额外的本地地址al 指令(和/或限制可以与后端建立的 TCP 连接数)。

【讨论】:

以上是关于NGINX:超过 65535 个连接限制的主要内容,如果未能解决你的问题,请参考以下文章

iptables限制同一IP连接数,防防CC/DDOS攻击

nginx限制连接

导出Excel功能,如果行数超过65535行,怎么解决

Java类文件最大限制

WIN7的IIS对并发连接数有限制么

Nginx限制访问次数和并发数