NGINX 1.9.1 新特性:套接字端口共享

英文原文地址:Socket Sharding in NGINX Release 1.9.1
译者:UPYUN CDN 开发工程师 其实不想走html

NGINX 1.9.1 发布版本中引入了一个新的特性 —— 容许套接字端口共享,该特性适用于大部分最新版本的操做系统,其中也包括 DragonFly BSD 和内核 3.9 之后的 Linux 操做系统。套接字端口共享选项容许多个套接字监听同一个绑定的网络地址和端口,这样一来内核就能够将外部的请求链接负载均衡到这些套接字上来。(对于 NGINX Plus 的用户来讲,该特性将会在年末发布的版本 7 中获得支持)nginx

实际上不少潜在的用户但愿使用端口重用功能。其余服务也能够简单的进行热更新升级「NGINX 支持 多种方式 的热更新」。对于 NGINX 来讲,打开该选项能够经过在特定场景下减小链接锁竞争而提升性能。git

以下图所示,在该选项没有生效的前提下,一个单独的监听套接字会通知全部的工做进程,每一个进程则会试图争抢接管某个链接:github

图片描述

当该选项生效时,这个时候对于每一个网络地址和端口就会有多个监听套接字,每一个工做进程对应一个套接字,内核会决定由哪一个监听套接字(也就是决定哪一个工做进程)接管进来的链接。这个特性能够减小进程与进程之间为接收链接产生的锁竞争而提升多核系统的性能。可是,若是当一个工做进程处于阻塞操做时,这个时候不只会影响已经被该进程接收的链接,还会阻塞由系统准备分配给该进程的链接请求:网络

图片描述

配置套接字共享

以下面配置所示,能够经过在 listen 指令后添加新的参数 reuseport 来为 HTTP 或者 TCP(流模块)打开套接字端口共享功能:负载均衡

图片描述

对于套接字来讲,添加 reuseport 参数也就等于禁止了 accept_mutex 指令了,由于 mutex 对于 reuseport 来讲是多余的,不过对于那些不但愿使用套接字端口共享特性的端口来讲,咱们则有必要设置 accept_mutex。socket

reuseport 性能压力测试

我经过运行 wrk 压测工具来压测一个跑在 36 核亚马逊实例上并开启 4 个工做进程的 NGINX。为了减小网络对于测试结果的影响,咱们的客户端和 NGINX 都是运行在本地的,而且 NGINX 只返回 OK 字符串而不返回文件。我对比了三个不一样的配置,一个是默认的(等同于 accept_mutex on),另外一个是 accept_mutex off,还有一个则是 reuseport。正以下图所示,使用 reuseport 后每秒能处理的请求数比其余的两个增长了 2-3 倍,而且同时减小了平均延迟和平均延迟的标准差。工具

图片描述

我还尝试客户端和 NGINX 分别运行在不一样的主机上跑相关的压力测试,但这一次 NGINX 返回的是一个 HTML 文件。正以下表所示,与上图的结果相似,使用端口重用能减小请求的处理延迟,而且延迟标准差减小的更加明显(大概是 10 倍)。其余结果(并无在下表中显示)则更加让人欣喜。经过端口重用,请求的压力被各个工做进程均衡掉,而在默认条件下(也就是 accept_mutex 打开),一些工做进程会获得比较高的负载,而在 accept_mutex 关闭的时候,全部的进程都会显示负载比较高。性能

图片描述

在上述的压力测试中,请求的频率很高可是每一个请求并不须要复杂的处理。其余一些初步的测试也代表端口重用特性在网络流量匹配的时候最能提升性能。(该参数并不能在邮件模块的上下文监听指令中生效,由于邮件的网络流量并不能匹配这个特性)。咱们建议你在使用 reuseport 这个指令前先在你的 NGINX 实例上进行性能测试,而不是所有的 NGINX 实例都使用。对于测试 NGINX 的一些小提示,能够参考 Konstantin Pavlov 在 2014 NGINX 大会上的演讲测试

致谢

感谢在英特尔工做的卢英奇和 Sepherosa Ziehau,他们每一个人各自贡献了使得套接字端口共享生效的解决方案。NGINX 开发小组合并了他们俩的想法从而创造出目前看来比较理想的解决方案。

原文连接:http://io.upyun.com/2015/07/20/nginx-socket-sharding/

相关文章
相关标签/搜索