NGINX:超过65535个连接限制

时间:2015-12-04 02:32:52

标签: sockets nginx websocket getsockopt dragonfly-bsd

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

1 个答案:

答案 0 :(得分:2)

您收到的评论是正确的:

  

TCP连接由4元组(src_addr,src_port,dst_addr,dst_port)定义。如果客户端使用不同的IP地址和/或源端口,则可以在同一端口上连接到超过65536个客户端的服务器。示例:服务器IP在端口80上侦听0.0.0.1。所有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)close(2)根据需要连接到8080等端口上游。

请注意,尽管其服务器上下文不可能耗尽TCP端口(因为服务器在其所有连接中使用单个端口 - 例如,端口80),客户端的TCP端口耗尽是一种真正的可能性,取决于配置。您还必须考虑在客户端在连接上执行state goes to TIME_WAIT之后,the SO_REUSEPORT option持续大约60秒左右的时间段(以确保如果任何迟到的数据包确实通过,那么系统将知道如何处理它们。)

然而,话虽如此,请注意getsockopt(2)the sharding context presented in the referenced release notes and reuseport announcement of nginx 1.9.1,至少在Benchmarking reuseport in 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倍,并减少了延迟和延迟的标准偏差。

     

uint16_t

关于你的基本问题,传出TCP portsproxy_bind问题的解决方案可能是在关注时不使用TCP的后端,和/或通过使用额外的本地地址{{3}}等指令(和/或限制可与后端建立的TCP连接数)。