3

与 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 个连接限制?

4

1 回答 1

3

您收到的评论是正确的:

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()callsocket(2)和系统调用来接管端口,例如bind(2),然后在无限循环中调用),而是它也可能是上游服务器的客户端(根据需要调用并连接到 8080 等端口上的上游)。listen(2)80accept(2)socket(2)connect(2)

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

然而,话虽如此,请注意,至少在参考的发行说明和nginx 1.9.1 公告中提供的分片上下文中,SO_REUSEPORT选项与该困境完全无关——它只是具有可扩展多处理器的构建块内核和在内核下运行的应用程序之间的支持:getsockopt(2)reuseport65535

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

在 nginx 1.9.1 中对重用端口进行基准测试

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

于 2016-07-05T17:23:41.343 回答