共计 2524 个字符,预计需要花费 7 分钟才能阅读完成。
NGINX 发布的 1.9.1 版本引入了一个新的特性:允许使用 SO_REUSEPORT 套接字选项,该选项在许多操作系统的新版本中是可用的,包括 DragonFly BSD 和 Linux(内核版本 3.9 及以后)。该套接字选项允许多个套接字监听同一 IP 和端口的组合。内核能够在这些套接字中对传入的连接进行负载均衡。
(对于 NGINX Plus 客户,此功能将在年底发布的版本 7 中出现)
SO_REUSEPORT 选项有许多潜在的实际应用。其他服务也可以使用它来简单实现执行中的滚动升级(Nginx 已经通过不同的办法支持了滚动升级)。对于 NGINX 而言,启用该选项可以减少在某些场景下的锁竞争而改善性能。
如下图描述,当 SO_REUSEPORT 选项有效时,一个单独的监听 socket 通知工作进程接入的连接,并且每个工作线程都试图获得连接。
当 SO_REUSEPORT 选项启用是,存在对每一个 IP 地址和端口绑定连接的多个 socket 监听器,每一个工作进程都可以分配一个。系统内核决定哪一个有效的 socket 监听器(通过隐式的方式,给哪一个工作进程)获得连接。这可以减少工作进程之间获得新连接时的封锁竞争(译者注:工作进程请求获得互斥资源加锁之间的竞争),同时在多核系统可以提高性能。然而,这也意味着当一个工作进程陷入阻塞操作时,阻塞影响的不仅是已经接受连接的工作进程,也同时让内核发送连接请求计划分配的工作进程因此变为阻塞。
设置共享 Socket
为了让 SO_REUSEPORT socket 选项起作用,应为 HTTP 或 TCP(流模式)通信选项内的 listen 项直接引入新近的 reuseport 参数,就像下例这样:
http {
server {listen 80 reuseport;
server_name localhost;
…
}
}
stream {
server {listen 12345 reuseport;
…
}
}
引用 reuseport 参数后,对引用的 socket,accept_mutex 参数将会无效,因为互斥量(mutex)对 reuseport 来说是多余的。 对没有使用 reuseport 的端口, 设置 accept_mutex 仍然是有价值的。
reuseport 的基准性能测试
我在一个 36 核的 AWS 实例运行 wrk 基准测试工具测试 4 个 NGINX 工作进程. 为了减少网络的影响,客户端和 NGINX 都运行在本地,并且让 NGINX 返回 OK 字符串而不是一个文件。我比较三种 NGINX 配置:默认(等同于 accept_mutex on),accept_mutex off, 和 reuseport。如图所示,reuseport 的每秒请求是其余的两到三倍,同时延迟和延迟标准差也是减少的。
我又运行了另一个相关的性能测试——客户端和 NGINX 分别在不同的机器上且 NGINX 返回一个 HTML 文件。如下表所示,用 reuseport 减少的延迟和之前的性能测试相似,延迟的标准差减少的更为显著(接近十分之一)。其他结果(没有显示在表格中)同样令人振奋。使用 reuseport,负载被均匀分离到了 worker 进程。在默认条件下(等同于 accept_mutex on),一些 worker 分到了较高百分比的负载,而用 accept_mutex off 所有 worker 都受到了较高的负载。
Latency (ms) | Latency stdev (ms) | CPU Load | |
Default | 15.65 | 26.59 | 0.3 |
accept_mutex off | 15.59 | 26.48 | 10 |
reuseport | 12.35 | 3.15 | 0.3 |
在这些性能测试中,连接请求的速度是很高的,但是请求不需要大量的处理。其他的基本的测试应该指出——当应用流量符合这种场景时 reuseport 也能大幅提高性能。(reuseport 参数在 mail 上下文环境下不能用在 listen 指令下,例如 email,因为 email 流量一定不会匹配这种场景。)我们鼓励你先测试而不是直接大规模应用。关于测试 NGNIX 性能的一些技巧,看看 Konstantin Pavlov 在 nginx2014 大会上的演讲。
致谢
感谢 Sepherosa Ziehau 和 Yingqi Lu, 他们为 NGNIX 项目贡献了一个使用 socket 选项 SO_REUSEPORT 的方案。NGNIX 团队整合他们的贡献和想法所创建的,我们相信是一个理想的解决方案。
CentOS 6.2 实战部署 Nginx+MySQL+PHP http://www.linuxidc.com/Linux/2013-09/90020.htm
使用 Nginx 搭建 WEB 服务器 http://www.linuxidc.com/Linux/2013-09/89768.htm
搭建基于 Linux6.3+Nginx1.2+PHP5+MySQL5.5 的 Web 服务器全过程 http://www.linuxidc.com/Linux/2013-09/89692.htm
CentOS 6.3 下 Nginx 性能调优 http://www.linuxidc.com/Linux/2013-09/89656.htm
CentOS 6.3 下配置 Nginx 加载 ngx_pagespeed 模块 http://www.linuxidc.com/Linux/2013-09/89657.htm
CentOS 6.4 安装配置 Nginx+Pcre+php-fpm http://www.linuxidc.com/Linux/2013-08/88984.htm
Nginx 安装配置使用详细笔记 http://www.linuxidc.com/Linux/2014-07/104499.htm
Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm
Nginx 的详细介绍 :请点这里
Nginx 的下载地址 :请点这里
英文原文:Socket Sharding in NGINX Release 1.9.1
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-06/118675.htm