NGINX 1.9.1 引入了一项新功能,允许使用SO_REUSEPORT
套接字选项,该选项在许多操作系统的较新版本中可用,包括 DragonFly BSD 和 Linux(内核版本 3.9 及更高版本)。 此套接字选项允许多个套接字监听相同的 IP 地址和端口组合。 然后内核对各个套接字上的传入连接进行负载平衡。
编辑器 – 对于 NGINX Plus 用户,NGINX Plus Release 7 (R7) 及更高版本支持此功能。 有关该版本所有新功能的概述,请参阅我们博客上的“宣布 NGINX Plus R7” 。
SO_REUSEPORT
套接字选项有许多潜在的实际应用。 其他服务可以使用它来轻松地滚动升级可执行文件(NGINX 已经通过不同的方式支持滚动升级)。 对于 NGINX,启用此套接字选项可以通过减少锁争用来提高特定场景下的性能。
如图所示,当未启用SO_REUSEPORT
选项时,单个监听套接字会通知工作者有关传入的连接,并且每个工作者都会尝试建立连接。
启用SO_REUSEPORT
选项后,每个 IP 地址和端口组合都会有多个套接字监听器,每个工作进程一个。 内核确定哪个可用的套接字监听器(以及哪个工作器)获取连接。 这可以减少接受新连接的工作人员之间的锁争用,并提高多核系统的性能。 但是,这也可能意味着当一个工作程序因阻塞操作而停滞时,该阻塞不仅影响该工作程序已经接受的连接,还会影响内核自该工作程序被阻塞以来分配给该工作程序的连接请求。
要启用SO_REUSEPORT
套接字选项,请将新的repeatport
参数包含到 HTTP 或 TCP (流模块)流量的listen
指令中,如以下示例所示:
http { 服务器 {监听 80 重用端口; server_name localhost; # ... } } 流 { 服务器 {监听 12345 重用端口;#... } }
包含repeatport
参数还会禁用套接字的accept_mutex
指令,因为互斥锁对于repeatport
来说是多余的。 如果存在未设置repeatport
的端口,则仍然值得设置accept_mutex
。
repeatport
进行性能基准测试我在一个 36 核的 AWS 实例上使用 4 个 NGINX 工作程序运行了一个wrk基准测试。 为了消除网络效应,我在本地主机上运行了客户端和 NGINX,并且让 NGINX 返回字符串OK
而不是文件。 我比较了三种 NGINX 配置:默认配置(相当于accept_mutex on
)、 accept_mutex off
和repeatport
。 如图所示, reuseport
将每秒请求数提高了 2 到 3 倍,并且降低了延迟和延迟的标准偏差。
我还在不同的主机上使用客户端和 NGINX 运行了相关的基准测试,并且 NGINX 返回了一个 HTML 文件。 如下表所示,使用repeatport
后,延迟的减少与之前的基准测试类似,标准差的减少更为显著(几乎减少了十倍)。 其他结果(未在表中显示)也令人鼓舞。 使用repeatport
,负载可以均匀分布在各个工作进程中。 在默认条件下(相当于accept_mutex on
),一些工作者获得了更高百分比的负载,而当accept_mutex off
时,所有工作者都会经历高负载。
延迟(毫秒) | 延迟标准差(毫秒) | CPU 负载 | |
---|---|---|---|
默认 | 15.65 | 26.59 | 0.3 |
accept_mutex关闭 |
15.59 | 26.48 | 10 |
鲁塞波特 |
12.35 | 3.15 | 0.3 |
在这些基准测试中,连接请求率很高,但请求不需要大量处理。 其他初步测试也表明,当流量与此配置文件匹配时, reuseport
可以最大程度地提高性能。 (例如, reuseport
参数在邮件
上下文中的listen
指令中不可用,因为电子邮件流量肯定与配置文件不匹配。) 我们鼓励您测试repeatport
以确定它是否可以提高 NGINX 部署的性能,而不是全面应用它。 有关测试 NGINX 性能的一些技巧,请参阅Konstantin Pavlov 在 nginx.conf 2014 上的演讲。
感谢英特尔的 Yingqi Lu 和 Sepherosa Ziehau,他们为 NGINX 项目贡献了解决方案,使得能够使用SO_REUSEPORT
套接字选项。 NGINX 团队结合了两方贡献的想法,创造了我们认为理想的解决方案。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”