Nginx worker_connections 的最佳值

Aar*_*rti 47 nginx scalability connection worker-process

Nginx worker_connections“设置了一个工作进程可以打开的最大并发连接数。这个数字包括所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接。另一个考虑因素是实际的同时连接数不能超过当前最大打开文件数限制”。我对此有几个疑问:

  1. 为此,最佳或推荐值应该是多少?
  2. 使用大量工作连接的缺点是什么?

use*_*461 58

让我们采取务实的方法。

所有这些限制都是在上个世纪硬件缓慢且昂贵的情况下硬编码和设计的。现在是 2016 年,普通的 wall-mart 烤面包机可以处理比默认值更多的请求。

默认设置实际上很危险。在一个网站上拥有数百名用户并不令人印象深刻。

worker_process

一个相关的设置,让我们在讨论主题时解释它。

nginx 作为负载均衡器:

  • 1 个用于 HTTP 负载平衡的工作器。
  • 每个内核 1 个工作线程用于 HTTPS 负载平衡。

nginx 作为网络服务器:

这个很棘手。

一些应用程序/框架/中间件(例如 php-fpm)在 nginx 之外运行。在这种情况下,1 个 nginx worker 就足够了,因为通常是外部应用程序在进行繁重的处理并消耗资源。

此外,某些应用程序/框架/中间件一次只能处理一个请求,并且使它们过载会适得其反。

一般来说,1 个工人总是一个安全的赌注。

否则,如果您知道自己在做什么,则可以为每个核心放置一名工人。我认为这条路线是一种优化,并建议进行适当的基准测试和测试。

worker_connections

连接总数为worker_process * worker_connections。一半处于负载平衡器模式。

现在我们到了烤面包机部分。有许多被严重低估的系统限制:

  • ulimits 是 linux 上每个进程的最大打开文件数为 1k(在某些发行版上为 1k 软,4k 硬)
  • systemd 限制与 ulimits 大致相同。
  • nginx 默认为每个 worker 512 个连接。
  • 可能还有更多:SELinux、sysctl、supervisord(每个发行版+版本略有不同)

1k worker_connections

安全的默认值是将 1k 放在任何地方。

它的高度足以超过大多数内部和未知站点所遇到的情况。它足够低,不会达到任何其他系统限制。

10k worker_connections

拥有数千个客户是很常见的,尤其是对于公共网站。由于默认值较低,我不再计算我所看到的关闭的网站数量。

生产可接受的最小值为 10k。必须增加相关的系统限制以允许它。

没有太高的限制(如果没有用户,限制根本不起作用)。然而,过低的限制是非常真实的事情,会导致拒绝用户和死网站。

超过10k

10k很好很容易。

我们可以设置一个任意的 1000kk 限制(毕竟这只是一个限制),但这并没有多大实际意义,我们永远无法获得该流量,无论如何也无法接受。

让我们坚持 10k 作为一个合理的设置。需要(并且可以真正做到)更多的服务将需要特殊的调整和基准测试。

特殊场景:高级使用

有时,我们知道服务器没有太多资源,我们期望我们无能为力。我们宁愿拒绝用户也不愿尝试。在这种情况下,设置合理的连接限制并配置好的错误消息和处理。

有时,后端服务器运行良好,但只能达到一定的负载,再多一些,一切都会很快向南。我们宁愿放慢速度也不愿让服务器崩溃。在这种情况下,请使用严格的限制配置队列,让 nginx 缓冲所有热量,同时以上限速度排出请求。

  • 我喜欢这个答案,但为了对应该设置多高做出真正有根据的猜测,看来我们必须大致知道一个连接需要多少 RAM(例如,使用“sendfile”保存一个普通的静态文件),以便我们可以相乘来计算维持给定数量的“worker_connections”需要多少 RAM。 (2认同)
  • 您可以在不进行过多调整的情况下进行多达 10k 的处理。连接缓冲区在 ``sysctl`` 设置中设置。 (2认同)

Mar*_*cel 21

ulimit -a 会告诉你你的系统允许一个进程使用多少个打开的文件。

此外,net.ipv4.ip_local_port_range设置每个 IP 启用的套接字的总范围。

因此,您worker_connections不能超过其中任何一个,否则您的客户端连接将排队直到net.core.netdev_max_backlog- TCP 队列的总大小。

请记住,如果您使用 nginx 作为反向代理,则每个连接使用两个套接字。您可能想尝试一些与net.ipv4.tcp_fin_timeout内核 tcp 相关的超时,以尝试快速切换套接字状态。还有一点需要注意的是,每个socket都分配了TCP内存栈的内存,你也可以使用 设置一些TCP内存栈的限制,sysctl只要你有CPU和足够的文件处理程序,你就可以在RAM中施加更大的压力。

仅供参考,如果有足够的计算资源,有可能拥有一台具有大约 32GB 内存的服务器和一些虚拟网络接口来处理 1MM 同时连接,并使用 sysctl 进行一些内核调整。在我的测试中,当处理超过 1MM 并发送大约 700 字节的有效负载时,服务器需要大约 10 秒来更新大约 1.2MM 的并发客户端。接下来是通过绑定一些额外的网卡和放弃虚拟网卡来增加网络带宽。考虑到有效载荷、带宽和更新所有客户端的合理时间,可以与超过 1.2MM 的客户端实现伪近实时通信。

快乐调音!

  • 注意 `net.ipv4.ip_local_port_range` 仅与传出连接相关,与传入连接无关(典型情况是 nginx 在端口 80 和 443 上);请参阅[此处](/sf/answers/779074901/)。 (2认同)

小智 2

可以通过测试发现适当的大小,因为它会根据 Nginx 处理的流量类型而变化。

理论上,nginx可以处理:最大客户端数=worker_processes*worker_connections(*=multiply)和worker_processes=处理器数量

要查找处理器,请使用: grep process /proc/cpuinfo | 厕所-l