概述
NGINX以高性能的负载平衡器、缓存和web服务器而闻名,为世界上超过40%的最繁忙的网站提供支持。对于大多数用例,默认NGINX和Linux设置工作得很好,但是要获得最佳性能有时需要进行一些调优。这篇博文讨论了在调优系统时要考虑的NGINX和Linux的一些设置。
您几乎可以对任何设置进行调优,但是本文主要关注少数几个可使大多数用户受益的设置。如果您对NGINX和Linux有深入的了解,或者在我们的支持或专业服务团队的指导下,我们建议您更改一些设置,但在这里我们不介绍这些设置。专业的服务团队已经与一些世界上最繁忙的网站合作,以优化NGINX的最大水平的性能,并可与您的NGINX或NGINX +部署获得最大的工作。
介绍
假设您对NGINX体系结构和配置概念有基本的了解。本文不打算复制NGINX文档,但提供了各种选项的概述和相关文档的链接。
调优时要遵循的一个好规则是每次更改一个设置,如果更改不能提高性能,则将其设置回默认值。
我们首先讨论Linux调优,因为一些操作系统设置的值决定了您如何调优NGINX配置。
优化Linux配置
现代Linux内核(2.6+)中的设置适用于大多数目的,但是更改其中一些设置是有益的。检查内核日志中指示设置太低的错误消息,并按建议进行调整。这里我们只讨论在正常工作负载下最有可能从调优中获益的设置。有关调整这些设置的详细信息,请参阅Linux文档。
积压队列(The Backlog Queue)
以下设置与连接及其排队方式有关。如果传入连接的速率很高,并且性能水平不均衡(例如,某些连接似乎出现了停顿),那么更改这些设置可能会有所帮助。
- net.core.somaxconn - 可以排队等待NGINX接受的最大连接数。默认值通常很低,这通常是可以接受的,因为NGINX接受连接非常快,但如果你的网站流量很大,增加它是值得的。如果内核日志中的错误消息表明该值太小,则增加该值,直到错误停止。
注意:如果将此值设置为大于512,则将backlog参数更改为NGINX listen指令以匹配。
- net.core.netdev_max_backlog - 网卡在发送给CPU之前对数据包进行缓冲的速率。增加该值可以提高具有高带宽的机器的性能。检查内核日志,查看与此设置相关的错误,并参考网卡文档,获得关于更改此设置的建议。
文件描述符(File Descriptors)
文件描述符是操作系统资源,用于表示连接和打开的文件等。NGINX每个连接最多可以使用两个文件描述符。例如,如果NGINX正在代理,它通常为客户端连接使用一个文件描述符,为到代理服务器的连接使用另一个文件描述符,但如果使用HTTP keepalives,这个比例要低得多。对于服务于大量连接的系统,可能需要调整以下设置:
- sys.fs.file-max - 文件描述符的系统范围限制
- nofile - 用户文件描述符限制,在/etc/security/limits.conf文件中设置
临时端口(Ephemeral Ports)
当NGINX充当代理时,到上游服务器的每个连接都使用一个临时端口。您可能想要更改此设置:
- net.ipv4.ip_local_port_range - 端口值范围的开始和结束。如果您看到正在耗尽端口,请增加范围。常见的设置是端口1024到65000。
优化NGINX配置
下面是一些可能影响性能的NGINX指令。如上所述,我们只讨论您可以自行调整的安全指令。我们建议您不要在没有NGINX团队指示的情况下更改其他指令的设置。
工作进程
NGINX可以运行多个工作进程,每个进程都能够处理大量的并发连接。你可以控制工人进程的数量和他们如何处理连接与以下指示:
- worker_processes - NGINX工作进程的数量(默认值为1)。在大多数情况下,每个CPU核心运行一个工作进程效果很好,我们建议将这个指令设置为auto来实现这一点。有时您可能想要增加这个数字,例如当工作进程必须执行大量磁盘I/O操作时。
- worker_connections - 每个辅助进程可以同时处理的最大连接数。默认值是512,但是大多数系统都有足够的资源来支持更大的数字。适当的设置取决于服务器的大小和流量的性质,可以通过测试发现。
Keepalive连接(Keepalive Connections)
通过减少打开和关闭连接所需的CPU和网络开销,保持连接可以对性能产生重大影响。NGINX终止所有客户端连接,并创建到上游服务器的独立连接。NGINX支持客户端和上游服务器的keepalives。以下指令与客户保留文件有关:
- keepalive_requests - 客户端可以在一个keepalive连接上发出的请求数。默认值是100,但是更高的值对于使用负载生成工具进行测试特别有用,负载生成工具通常从单个客户端发送大量请求。
- keepalive_timeout - 空闲的保持连接保持打开状态的时间。
以下指示与上游纪念品有关:
- keepalive - 保持到上游服务器的空闲连接数,这些连接为每个工作进程保持打开状态。没有默认值。
要启用与上游服务器的保持连接,你还必须在配置中包括以下指令:
proxy_http_version 1.1;
proxy_set_header Connection "";
访问日志记录
记录每个请求都会消耗CPU和I/O周期,减少影响的一种方法是启用访问日志缓冲。通过缓冲,NGINX不再为每个日志条目执行单独的写操作,而是缓冲一系列条目,并在一个操作中将它们一起写到文件中。
要启用访问日志缓冲,请在access_log指令中包含buffer=size参数;当缓冲区达到大小值时,NGINX将缓冲区内容写入日志。要让NGINX在指定的时间内写入缓冲区,需要包含flush=time参数。当设置了这两个参数时,NGINX将向日志文件写入条目,此时下一个日志条目将不适合缓冲区,或者缓冲区中的条目分别比指定的时间更早。日志条目也是在工作进程重新打开其日志文件或关闭时编写的。要完全禁用访问日志记录,请在access_log指令中包含off参数。
Sendfile
操作系统的sendfile()系统调用将数据从一个文件描述符复制到另一个文件描述符,通常实现零拷贝,这可以加速TCP数据传输。要使NGINX能够使用它,需要在http上下文或服务器或位置上下文中包含sendfile指令。NGINX可以将缓存或磁盘上的内容写入套接字中,而不需要向用户空间进行任何上下文切换,这使得写入非常快,并且消耗更少的CPU周期。但是,请注意,由于使用sendfile()复制的数据绕过了用户空间,所以它不受常规NGINX处理链和更改内容的过滤器(如gzip)的约束。当配置上下文同时包含sendfile指令和激活内容更改过滤器的指令时,NGINX会自动禁用该上下文的sendfile。
限制
您可以设置各种限制,以帮助防止客户端消耗过多的资源,这会对系统的性能以及安全性和用户体验造成不利影响。以下是一些相关的指示:
- limit_conn and limit_conn_zone – 限制NGINX接受的客户端连接的数量,例如从一个IP地址。设置它们可以帮助防止个别客户端打开太多的连接并消耗超过其共享的资源。
- limit_rate - 限制每个连接向客户端传输响应的速率(因此打开多个连接的客户端可以为每个连接消耗这个数量的带宽)。设置限制可以防止系统因某些客户端而超载,从而确保所有客户端的服务质量更加均衡。
- limit_req and limit_req_zone - 限制NGINX处理请求的速率,它具有与设置limit_rate相同的好处。它们还可以提高安全性,特别是对于登录页面,方法是将请求速率限制在一个对人类用户来说合理的值,但是对于试图用请求(例如DDoS攻击中的机器人)淹没应用程序的程序来说太慢了。
- max_conns上游配置块中服务器指令的参数 - 设置上游组中服务器接受的最大并发连接数。设置限制可以帮助防止上游服务器超载。将值设置为0(缺省值为0)意味着没有限制。
- queue (NGINX Plus) - 创建一个队列,当上游组中的所有可用服务器都达到max_conns限制时,将在其中放置请求。这个指令设置队列中请求的最大数量,以及它们在返回错误之前等待的最长时间(默认为60秒)。如果省略此指令,请求不会排队。
缓存和压缩可以提高性能
NGINX的一些可以用来提高web应用程序性能的附加特性并不属于调优的范畴,但是值得一提,因为它们的影响是相当大的。它们包括缓存和压缩。
缓存
通过在NGINX实例上启用缓存(该实例用于平衡一组web或应用程序服务器的负载),您可以显著提高客户机的响应时间,同时显著降低后端服务器的负载。缓存本身就是一个主题,我们在这里就不赘述了。参见NGINX Plus管理指南。
压缩
压缩发送到客户端的响应可以极大地减小它们的大小,因此它们使用更少的网络带宽。但是,因为压缩数据会消耗CPU资源,所以当真正值得减少带宽使用时,它才是最有用的。需要注意的是,不应该为已经压缩的对象(如JPEG文件)启用压缩。有关更多信息,请参见NGINX Plus管理指南。