转载请备注来源: 《nginx性能优化专题整理》 | shuwoom.com

摘要

本文主要介绍nginx性能优化的相关知识,系统梳理从内核参数优化、Nginx配置优化到缓存优化以及负载均衡架构设计。由点到面再到整体来系统介绍nginx性能优化的方方面面知识。

sysctl.conf操作

查看系统参数:

sysctl -a

查看tcp网络相关的系统参数

sysctl -a|grep net.ipv4.tcp

启用最新系统参数

sysctl -p

内核参数优化

Linux内核参数默认考虑的是最通用的场景,但是在高并发的web服务器上,这个不太适用。所以,我们需要根据实际的业务特点来进行调整,提高Nginx的并发性能。如下是几个比较关键的参数。我们可以通过修改/etc/sysctl.conf来修改内核参数。

增大套接字读写缓存

  • 读缓冲区,缓存了远端发送过来的数据。如果读缓冲区已满,就不能再接收新的数据
  • 写缓冲区,缓存了要发出去的数据。如果缓冲区已满,应用程序的写操作就会阻塞

所以,为了提高网络的吞吐量,通常要调整这些缓冲区大小。

备注:下图转载自《Linux性能优化实战》

img


TCP配置优化

数值仅提供参考,具体配置请结合实际场景来调整。

tcp_max_tw_buckets

这个参数表示操作系统允许TIME_WAIT套接字数量的较大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。

net.ipv4.tcp_max_tw_buckets = 5000

tcp_fin_timeout

当服务器主动关闭链接时,socket保持在FIN_WAIT_2状态的较大时间

net.ipv4.tcp_fin_timeout = 30

tcp_tw_reuse

开启重用功能,允许将TIME-WAIT状态的sockets重新用于新的TCP链接。设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接,这意味着服务器总会有大量的TIME_WAIT状态的连接存在。

net.ipv4.tcp_tw_reuse = 1

ip_local_port_range

定义UDP和TCP链接的本地端口取值范围。调高系统的IP以及端口数据限制,从而可以接受更多的连接。

net.ipv4.ip_local_port_range = 1024 65000

tcp_max_syn_backlog

这个参数表示TCP三次握手建立阶段接受SYN请求列队的较大长度,默认1024,将其设置的大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的链接请求。

net.ipv4.tcp_max_syn_backlog = 8192

tcp_syncookies

与性能无关,用于解决TCP的SYN攻击。

net.ipv4.tcp_syncookies = 1

tcp_keepalive_time

当keepalive启动时,TCP发送keepalive消息的频度,用于确认TCP连接是否有效;默认是2小时,将其设置为10分钟,可以更快的清理无效链接。

ner.ipv4.tcp_keepalive_time = 600

更多跟TCP优化相关的参数,如下表所示:

备注:下图转载自《Linux性能优化实战》

img

NGINX配置文件优化

异步I/O(thread_pool)

thread_pool的使用方法见我写的文章《Nginx配置文件(nginx.conf)详解》。异步I/O允许进程进行不受阻塞或不需等待I/O完成的I/O操作。那么,我们在什么情况下可以使用这个配置项呢?

我们知道,Nginx是基于事件模型的异步服务器,但是对于阻塞事件的处理,会导致后面其他网络事件处理被迫延时。如下图所示,后面的事件需要等待前面的阻塞事件(文件读写、耗时的数据库操作)处理完后才可以进入处理。

img

未启用thread_pool时,Nginx事件处理流程如下图所示:

NGINX-Event-Loop2

而使用了thread_pool后,其处理流程编程如下:

Thread pools help increase application performance by assigning a slow operation to a separate set of tasks

这时候Nginx就多了一个任务队列和线程池。当出现一个阻塞的事件时,nginx会把它丢到任务队列中,然后继续处理下一个事件。这样每个事件的处理就不会因为某个阻塞事件而导致整体被延误。

关于这个参数的详细细节,可以阅读国外网友写的一篇文章:https://www.nginx.com/blog/thread-pools-boost-performance-9x/

例如:

thread_pool one threads=128 max_queue=0;
thread_pool two threads=32;

http {

    server {
        location /one {
            aio threads=one;
        }

        location /two {
            aio threads=two;
        }
    }
…
}

worker_process

nginx进程数,建议按照cpu的数目来指定,一般是相等。如8核cupu:

worker_process 8;

worker_cpu_affinity

为每个进程分配cpu,上例中将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

或者直接适用auto选项,让nginx自动绑定可用的cpu核。

worker_cpu_affinity auto;

worker_rlimit_nofile

这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

worker_rlimit_nofile 102400;

sendfile

当应用程序传输文件时,内核首先缓冲数据,然后将数据发送到应用程序缓冲区。应用程序最后将数据发送到目的地。

sendfile方法则是对输出传输方法进行改进,其中数据在操作系统内核空间内的文件描述符之间复制,而不将数据传输到应用程序缓冲区,这样极大提高了系统资源的利用率。使用详细参数和方法见:《Nginx配置文件(nginx.conf)详解》](https://shuwoom.com/?p=4292)。

http {
    sendfile on;
}

epoll

使用epoll的I/O模型

use epoll;

worker_connections

每个进程允许的最大连接数,理论上每台nginx服务器的最大连接数为worker_process*worker_connections。

worker_connections 102400;

keepalive_timeout

keepalive超时时间。

keepalive_timeout 60;

client_header_buffer_size

客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。

client_header_buffer_size 4k;

open_file_cache_valid

这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。

open_file_cache_valid 30s;

open_file_cache_min_uses

这个是指多长时间检查一次缓存的有效信息。

open_file_cache_min_uses 1;

缓存的使用

详细的文章介绍可以参看我写的文章:《Nginx缓存机制详解》

负载均衡

详细的文章介绍可以参看我写的文章:NGINX负载均衡搭建

转载请备注来源: 《nginx性能优化专题整理》 | shuwoom.com

打赏

发表评论

电子邮件地址不会被公开。