当前位置: 首页 > 科技观察

浅谈Nginx性能调优

时间:2023-03-18 18:31:58 科技观察

Linux系统参数优化下面提到的一些配置需要较新的Linux(2.6以上)内核支持。笔者使用的是CentOS7.4,内核版本3.10,如果不能满足需要,最好相应升级,毕竟打补丁是吃力不讨好的事。对于系统级调优,我们通常会修改文件描述符限制、缓冲区队列长度和临时端口数。文件描述符限制因为每个TCP连接都占用一个文件描述符,一旦文件描述符用完,新的连接就会返回“Toomanyopenfiles”等错误。为了提高性能,我们需要修改修改:1.限制在系统级别编辑文件/etc/sysctl.conf,增加如下内容:1.`fs.file-max=10000000`2.`fs.nr_open=10000000`2。在用户级别限制编辑文件/etc/security/limits.conf,添加如下内容:1.`*hardnofile1000000`2.`*softnofile1000000`这里只要保证用户级别限制不大于系统级别即可限制,否则可能会出现无法通过SSH登录系统的问题。修改后执行如下命令:1.`$sysctl-p`执行命令ulimit-a可以查看修改是否成功。TCP连接队列长度编辑文件/etc/sysctl.conf,添加如下内容:1.`#Thelengthofthesynquene`2.`net.ipv4.tcp_max_syn_backlog=65535`3.`#Thelengthofthetcpacceptqueue`4.`net.core.somaxconn=65535`tcp_max_syn_backlog用于指定半连接SYN队列的长度。当有新的连接到来时,系统会检测半连接的SYN队列。如果队列已满,无法处理SYN请求,ListenOverflows和ListenDrops中添加统计计数somaxconn指定满连接ACCEPT队列长度。当队列满时,客户端发送的ACK包将无法正确处理,返回“connectionresetbypeer”错误。Nginx会记录一个错误日志“noliveupstreamswhileconnectingtoupstreams”如果出现上述错误,我们需要考虑增加这两项的配置。临时端口由于使用了Nginx作为代理,每个上游web服务的TCP连接都会占用一个临时端口,所以我们需要修改ip_local_port_range参数,修改/etc/sysctl.conf文件,增加如下内容:1.`net.ipv4。ip_local_port_range=102465535`2.`net.ipv4.ip_local_reserved_ports=8080,8081,9000-9010`其中参数ip_local_reserved_ports用于指定保留端口,防止服务端口被占用而无法启动。Nginx参数优化Nginx参数优化主要围绕nginx.conf配置文件展开,下面不再详述。工作进程Nginx的强大性能的一个重要原因是它采用了多进程非阻塞I/O模型,所以我们一定要利用好这个:worker_processesNginx默认只有一个master进程和一个worker进程.我们需要对其进行修改,可以设置指定的个数,也可以设置为auto,即系统的CPU核数。较多数量的worker将导致进程之间对CPU资源的竞争,从而导致不必要的上下文切换。所以这里我们可以设置为CPU核数:worker_processesautoworker_connections每个worker可以处理的并发连接数。默认值512是不够的。我们适当增加:worker_connections4096Nginx支持以下I/O多路复用方式处理连接:select、poll、kqueue、epoll、rtsig、/dev/poll、eventport。它们适用于不同的操作系统,其中epoll在linux系统上效率最高:使用epollKeepAlive为了避免Nginx对web服务频繁的建立和断开连接,我们可以开启自HTTP1.1开始支持的KeepAlive长连接特性,它可以大大降低CPU和网络开销,也是我们实战中对性能提升最大的部分。keepalive必须配合proxy_http_version和proxy_set_header使用,参考配置如下:1.`upstreamBACKEND{`2.`keepalive300;`3.`server127.0.0.1:8081;`4.`}`5.`服务器{`6.`listen8080;`7.`location/{`8.`proxy_passhttp://BACKEND;`9.`proxy_http_version1.1;`10.`proxy_set_headerConnection"";`11.`}`12.`}`keepalive所在的位置既不是超时时间,也不是连接池数量,官方解释如下:connections参数设置了每个worker进程的缓存中保存到上游服务器的最大空闲keepalive连接数。当超过这个数字时,最近最少使用的连接将被关闭。可见其意思是“最大空闲长连接数”。超过这个数量的空闲长连接将被回收。当请求数稳定流畅时,空闲长连接数会很少(接近于0)。现实中,请求的数量不可能一直顺畅稳定。当请求数波动时,空闲长连接数也随之波动:当空闲长连接数大于配置值时,会导致该连接被回收;当长连接不够时,会重新建立一个新的长连接。所以,如果这个值太小,会造成连接池频繁的回收、分配、回收。为避免出现这种情况,可根据实际情况适当调整该值。在我们的实际情况下,目标QPS为6000,web服务响应时间为200ms左右,所以需要1200个左右的长连接,keepalive值是长连接数的10%~30%的值就够了。这里我们取300,如果不想计算,直接设置为1000也是可行的。在Access-Log缓存中记录日志的I/O开销相对较高。幸运的是,Nginx支持日志缓存。我们可以利用这个功能来减少写入日志文件的频率,从而提高性能。buffer和flush参数可以结合使用来控制缓存行为:1.`access_log/var/logs/nginx-access.logbuffer=64kgzipflush=1m`buffer指定缓存大小,当buffer达到指定的大小时缓冲时间,Nginx会将缓存的日志写入文件;flush指定缓存超时时间,当flush指定的时间到来时,也会触发将缓存日志写入文件的操作。文件描述符限制上一节修改了Linux系统的文件描述符限制。Nginx配置中也有对应的配置项:worker_rlimit_nofile。理论上这个值应该设置为/etc/security/limits.conf的值除以worker_processes的值,但实际上不可能平均分配每个进程,所以这里只需要设置为与/etc/security/limits.conf从经验可以看出,它基本上是围绕着Nginx的Errorlog,然后针对一些比较大的性能瓶颈进行了一些改进。Nginx可以优化的地方有很多。本文只介绍了其中的一小部分,但是已经足够满足我们的使用场景了。