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 个连接限制的主要内容,如果未能解决你的问题,请参考以下文章