NGINX性能调优简要
(译者注:以下是数天前NGINX官方博客发表的一篇有关nginx性能优化的文章,内容简明扼要,值得一读。译文在原文基础上略有变动,如有不足,欢迎指正。)
NGINX作为一款高性能负载均衡器,缓存和web服务器被大家所熟知,为全世界40%的网站提供着服务。NGINX和Linux系统中的大多数默认配置对普通应用来说已经很合适,然而要想达到更高的性能以应对高负载场景那么一些性能优化是必须的。这篇文章将会探讨一些在性能调优时涉及到的NGINX和Linux系统参数。当然可供调节的参数众多,我们这里只会涉及部分对大多数用户来说被使用最多的。其他没有被涉及到的参数多是需要对系统有深入了解之后才需要接触到的。
简介
我们假定此文读者对NGINX的基本架构和配置有一定了解,此文不会重复NGINX文档中的内容,如有涉及我们仅会给出链接。
在做性能调优时一个最佳实践是一次只动一个参数,如果调整后未达到预期效果,则将其修改回初始值。我们将从Linux系统的一些参数开始讲起,这些参数将对后续的NGINX配置调整有着至关重要的作用。
Linux 配置
现代Linux内核(2.6+)中的很多参数设置都是十分到位的,但是仍然有一些是需要我们进行调整的。如果一些默认的值设置得太小,那么在内核日志中将记录着错误信息,这预示着我们需要对其中一些参数进行调整了。在众多选项当中我们只会涉及到对大多数负载场景都实用的,请参考Linux系统文档以了解更多有关这些选项的细节。
Backlog Queue
下面的设置与网络连接和连接队列有直接关联。如果你有大量的接入请求,且偶尔出现一些失效请求的话,那么下面的设置将起到优化效果。
net.core.somaxconn
此参数控制NGINX等待连接的队列大小。因NGINX处理连接的速度快,所以一般这个参数不建议被设置太大,但是默认值有点偏低,所以针对大流量网站来说调整这个参数是必须的,如果此参数被设置多低那么有可能在内核日志中看到报错,这时需要调整此参数直到报错消失为止。注意,如果此参数设置大于512的话,则需要对NGINX配置中的listen指令中的backlog参数进行同步调整。
net.core.netdev_max_backlog
此参数控制数据包在进入CPU处理前,在网卡中被缓存的量,需要处理大带宽的机器需要增加此参数的值。设置此参数需要参考具体的网卡的文档或者根据系统错误日志进行调整。
File Descriptors
文件描述符是系统在处理如网络连接和打开文件时的系统资源。NGINX中每个连接的建立可能需要占用两个文件描述符,例如代理模式下,一个用来处理客户端连接,一个用来处理到后端的连接,而如果HTTP keepalives被启用的话对文件描述符的消耗会轻松一些。需要处理高并发的机器建议调整下面的参数:
sys.fs.file_max
这个参数影响系统全局的文件描述符打开数量限制。
nofile
此参数影响单个用户的文件描述符数量,在/etc/security/limits.conf中进行设置。
Ephemeral ports
当NGINX被作为代理服务器时,每个到后端服务器的连接将占用一个临时的,或短期的端口。
net.ipv4.ip_local_port_range
此参数控制可被用作临时端口的起始范围,一个通用设置是1024-65000
net.ipv4.tcp_fin_timeout
此参数控制一个连接使用完毕后端口被回收再利用的超时时间,一般默认设置为60秒,但是一般设置降低到30或者15秒都是没有问题的。
NGINX 配置
下面介绍NGINX中对性能有影响的参数,如下面提到的一样,我们只讲解一些适用于大多数用户的参数进行调整,其他未提及的可能是不建议调整的。
Worker Processes
NGINX可以同时启动多个worker进程,每个进程处理大量的连接,通过调整下面的参数可以控制启动的进程数量和每个进程所处理的连接数量。
此参数控制NGINX启动进程的数量,在多数情况下每个cpu核心分配一个进程是最佳的,将参数值设置为auto即可达到。很多场景下都需要增加此参数的值,如在需要处理大量磁盘I/O的场景。默认的值是1。
此参数控制在同一时刻单个进程可以处理的最大连接数。默认值512,但大多数系统都可以处理更大的量。其最佳值与实际场景和系统有关,需要经过反复测试才能得出。
Keepalives
Keepalive连接降低连接的建立和关闭对CPU和网络的消耗,对性能有着十分重要的影响。NGINX会关闭所有客户端的连接,且与后端服务器的连接都是独立的。NGINX支持到客户端和后端的keepalive,下面的参数对客户端keepalive进行控制:
此参数控制通过单个keepalive连接可以处理的客户端请求数量,默认值是100,可以调整为更大的值,特别是在通过单个客户端进行压力测试的时候。
此参数控制单个keepalive连接在空闲状态保持连接的时间。
下面的参数对后端keepalive进行控制:
此参数控制单个worker进程保持到upstream server的keepalive连接数量,且默认没有设置。如需启动到后端的keepalive连接则需要进行如下设置:
proxy_http_version 1.1;
proxy_set_header Connection “”;
Access Logging
请求产生的日志记录对CPU和I/O都有消耗,一个可以降低资源消耗的办法是启用日志缓存。启用日志缓存后,NGINX将缓存部分请求日志,然后一次性写入文件。要启用日志缓存只需要在access_log中增加“buffer=size”的设置即可,size值控制缓存的大小,同时也可以设置“flush=time”以控制缓存的时间,设置了两个参数后,NGINX会在缓存被充满或者日志条目数达到flush值时回写日志。在worker进程重启或者关闭时也会回写日志。而永久禁用日志记录也是可以实现的。
Sendfile
Sendfile 是一项操作系统特性,可以被NGINX启用。它通过对数据在文件描述符之间进行in-kernel copying来提供更快的tcp数据传输处理,一般通过zero-copy技术实现。NGINX使用它来完成缓存数据或者磁盘数据到socket的写操作,不产生任何的用户空间上下文切换开销,可降低CPU负载和提高处理速度。当启用sendfile特性之后,由于数据不经过用户空间,使得对数据内容进行处理的filter将不起作用,例如gzip filter将默认被禁用。
Limits
NGINX也为用户提供设置连接限制的能力,用来对客户请求的资源进行控制,对系统性能,用户体验和安全性也产生极大的影响。下面是部分用于请求限制的指令:
这两个指令用来控制NGINX可接收的连接数,例如来自单个客户端IP的连接请求。这有助于限制客户端建立过多的连接并消耗过多资源。
这个指令控制单个连接允许的客户端最大带宽。这可以避免系统被部分客户端耗尽资源,保证了为每个客户端请求提供服务的质量。
这两个指令可以控制NGINX的请求回复水平,以不至于被部分客户端拖垮。也被用来加强安全性,特别是对登陆页面等进行有效的保护。
这个指令用来控制到后端服务器的最大连接数,保护后端服务器不被拖垮,默认值是zero,没有任何限制。
如果max_conns被设置,那么此参数对超过最大连接时的状态产生影响,可以设置队列中请求的个数和缓冲时间,如果没有设置此参数,则队列不存在。
其他设置
NGINX还有一些特性能对某些特定场景下的应用起到性能优化作用,我们将探讨其中的两个特性。
缓存
当把NGINX作为负载均衡器来使用的场景下,启用cache可以显著改善到客户端的响应时间,且显著降低后端服务器的压力。如需了解更多NGINX的caching设置,可以参考此链接:: NGINX Admin Guide – Caching.
压缩
对回应内容进行压缩将有效降低回应内容的大小,降低带宽消耗,然而压缩将增加CPU的开销,所以带宽成本较高时启用才是明智之举。需要明确注意的是不要对已经压缩的内容启用压缩,例如jpeg格式的图片,如需了解更多有关压缩的设置可以参考此文档: NGINX Admin Guide – Compression and Decompression
更多内容可参考:
- Benchmarking NGINX
- NGINX documentation
- NGINX and NGINX Plus features
- NGINX Plus Technical Specifications