轻松提升nginx性能
As your know, This is a transiation,原文: Socket Sharding in NGINX Release 1.9.1
NGINX发布版1.9.1介绍了新的特性,支持socket的SO_REUSEPORT选项,这个选项在许多操作系统的新版本有效,包括 DragonFly BSD和Linux(3.9+内核)。这个选项允许多个socket监听同个IP地址和端口的组合。内核负载均衡这些进来的sockets连接,将这些 socket有效的分片。
这个socket的SO_REUSEPORT选项已经有许多现实世界的应用。对NGINX而言,它通过分布进程上的连接以提升性能。
正如下图所描述的,当SO_REUSEPORT选项没开启时,连接进来时监听socket默认会通知某个进程。如果您包含了accept_mutex off这个指令,此时会唤醒所有的工作进程,它们将为了得到它产生竞争。这就是所谓的惊群现象。
(小解释下:如果使用epoll且不用锁,当监听端口有读操作时,是会产生惊群现象的)
启用SO_REUSEPORT选项后,每个进程将有个独立的监听socket。内核决定哪个是有效的socket(进程)得到这个连接。
这样做降低了延迟并提高了工作进程的性能,它也意味着工作进程在准备处理它们前被赋予了新的连接。
配置socket分片
要开启SO_REUSEPORT选项,将新的参数reuseport加到listen指令的后面,像以下例子这样:
http {
server {
listen 80 reuseport;
server_name localhost;
…
}
}
包含这个reuseport参数后将禁用这个监听socket的accept_mutex,因为锁变得多余了。如果你不想用reuseport在端口上设置accept_mutex仍然是值得做的。
基准测试性能的提升
我在4个NGINX工作进程36核AWS实例上跑了 wrk基 准测试,我的客户端和NGINX都在本地上,并且让NGINX只返回OK字符串。我比较了3种NGINX配置:accept_mutex on(默认),accept_mutex off,还有reuseport。如图所现,reuseport每秒提升了2到3倍的请求,同时降低了延迟和stdev指标。
我另外跑了一个更加真实的测试,将客户端和NGINX分离到不同的主机并且让NGINX返咽一个HTML页面文件。正如图表所显示的,带 reuseport的降低的延迟跟上面的测试很接近,并且stdev的也是。其它的测试结果也是很令人鼓舞的。由于reuseport,负载更加均衡的分 配到各工作进程。在默认情况下(accept_mutex on),一些工作进程表现的各加均衡,
accept_mutex off情况下则有些表现的高低不下。
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
致谢
感谢Sepherosa Ziehau和Yingqi Lu,他们在NGINX项目中使用了SO_REUSEPORT选项。NGINX团队借鉴他们的方法,并在NGINX创建了我们觉得更理想的方案。
推荐阅读:用lua让nginx成为应用服务器