反向代理服务器Nginx——性能调优篇

2,150 阅读8分钟

并发处理机制

一般情况下并发处理机制有三种:多进程、多线程和异步机制Nginx对于并发的处理同时采用了这三种机制。当然,其异步机制使用的是异步非阻塞的方式。

我们知道Nginx的进程分为两类:master进程与worker进程,每个master进程可以生成多个worker进程,所以其是多进程的。每个worker进程可以同时处理多个用户请求,每个用户请求会由一个线程来处理,所以其是多线程的。

那么,如何解释异步机制worker进程采用的是epoll多路复用机制来对后端服务器进行处理的。当后台服务器返回结果后,后端服务器就会回调epoll多路复用器,由多路复用器对相应的worker进行通知,此时worker进程就会挂起当前正在处理的事务,拿IO返回结果去相应客户端请求,响应完毕后,会继续执行挂起的事务,这个过程是异步非阻塞的。关于IO多路复用可以参考IO多路复用这篇文章,讲得很详细。

image.png

全局模块调优

worker_processes

打开nginx.conf配置文件,可以看到worker_processes的默认值为1,如下图所示

image.png

当我们把它改成2,并运行时,查看运行的Nginx运行的进程如下图所示

image.png

worker_processes用于指定Nginx的工作进程数量,其数值一般设置为CPU内核数量,或者内核数量的整数倍。不过需要注意,该值不仅仅取决于CPU内核数量,还与硬盘数量及负载均衡模式相关。在不确定时可以指定其值为auto

image.png

worker_cpu_affinity

worker进程与具体的哪个内核进行绑定,不过,若指定worker_processes的值为auto,则无法设置worker_cpu_affinity

image.png

该设置是通过二进制进行的,每个内核使用一个二进制位来表示,0代表内核关闭,1表示内核开启,也就是说,有几个内核,就需要使用几个二进制位。

image.png

worker_rlimit_nofile

worker_rlimit_nofile用于设置一个worker进程所能够打开的最多文件数量,其默认值与当前的Linux系统可以打开的最大文件描述符数量相同。

我们可以通过命令ulimit -n查看自己系统的可以打开的最大文件描述符数量,如下图所示

image.png

可以使用ulimit -n 65535把能打开的文件描述数量改成65535个(这只是临时修改,重启服务器后又会失效),想要永久修改打开的最大文件描述数量,修改/etc/security/limits.conf文件,修改soft nofile 65535 hard nofile 65535这两行。

events模块调优

worker_connection 1024

设置每一个worker进程可以并发处理的最大连接数。该值不能超过worker_rlimit_nofile的值。

accept_mutex

  • on:默认值,表示一个新连接到达时,那些没有处于工作状态(阻塞状态)的worker将以串行方式来处理这个连接。请求还没有过来时,最初的worker进程的状态都是处于阻塞状态的,因为缺少相应的资源,如果accept_mutex设置为on,当连接请求过来时,那么把worker进程从阻塞状态变成就绪状态的激活资源是互斥锁,只有一个worker进程能够获得互斥锁进入就绪状态(一般都是阻塞队列头元素),分到了时间片就会进入运行状态。其他没有获得互斥锁的worker进程还是处于阻塞状态。

  • off:表示当一个新连接到达时,所有的worker都会被唤醒,不过只有一个worker能获得取新连接,其他的worker会重新进入阻塞状态,这就是惊群现像。请求还没有过来时,激活资源是新连接,请求过来时,所有的worker都会变成就绪态,并且竞争连接资源,没有得到连接资源的worker进程又会变成阻塞状态。

nginx的作者对于惊群的解释:apache服务器进程一般是成百上千的,一旦发生惊群,会对系统影响特别大,但是nginx的工作进程最多是几十个,一个新连接来了之后,所有的进程的状态从阻塞状态变成就就绪状态,对系统的影响不大,实际工作中,

举个例子,比如1000多的请求过来时,相当于一把米,如果accept_mutex设置为on的话,相当于每次取出worker阻塞队列头元素,比于成一只鸡,每次都是取出一只鸡喂一粒米,这样会很慢;如果accept_mutex设置为on的话,因为所有阻塞的worker都已经唤醒了,相当于直接将这把米一撒,所有的鸡都可以直接吃,这样效率肯定是高的。

所以,高并发情况下,一般设置成off,并发量不大的系统设置成on

accept_mutex_delay

当上面的参数accept_mutex设置成on时,表示阻塞队列中队首的worker尝试获取互斥锁的时间间隔,默认值为500毫秒。即阻塞队列中队首的worker每隔500毫秒会查看是否有新连接过来,如果有的话就会尝试获取互斥锁。

multi_accept on

  • off:系统会逐个拿出连接按照负载均衡策略,将其分配给当前处理连接数个数最少的worker
  • on:系统会实时的统计出各个worker当前正在处理的连接个数,然后会按照缺编最多的worker,一次性将这么多的新连接分配给该worker.

设置中的缺编指的是因为一般一个worker最大能处理的并发连接请求数量一般是1024,如果当前worker进程处理的连接数量越小,即1024-当前进程处理的连接数量=缺编数量。设置成on的话会将请求一次性给了缺编最大的worker进程,这种方式处理比较快,而设置成off的话会一个一个给当前处理连接数量最少的worker进程,这种方式处理比较慢但是也不一定说multi_accept on就比off好,因为on的话需要mater实时计算所有worker的缺编,也会占用很多的系统资源

use epoll

设置worker与客户端连接的处理方式,Nginx会自动选择适合当前系统的最高效的方式,当然,也可以使用use指令明确指定所要使用的连接处理方式。use的取值有这几种:select | poll | epoll | rtsig | kqueue | /dev/poll

  • select | poll | epoll:这是三种多路复用机制,selectpoll工作原理几乎相同,而epoll效率最高,是现在使用最多的一种多路复用机制。
  • rtsigrealtime signal,实时信号,Linux2.2.19+的高效廉洁处理方式,但是在Linux2.6版本后不再支持该方式。
  • kqueue:应用在BSD系统上的epoll
  • /dev/pollUnix系统上使用的poll.

http模块调优

非调优属性简介

image.png

  • include mime.type:表示将/usr/local/nginx/conf/mime.type文件包含进来,mime.type文件指定文件类型,可以打开该文件看一下如下图所示

image.png

  • default_type application/octet-stream:表示对于无扩展名的文件,默认其为application/octet-stream类型,即Nginx会将其作为一个八进制流文件来处理。

  • charset utf-8:设置请求与响应的字符编码。

sendfile on

设置为on表示开启Linux系统的零拷贝机制,否则不启用零拷贝,当然开启后是否起作用,要看所使用的系统版本,CentOS6及其以上版本支持sendfile零拷贝。关于零拷贝可以参考:深入理解零拷贝这篇文章,讲得很详细。

tcp_nopush on

  • on:以单独的数据包形式发送Nginx的响应头信息,而真正的响应体数据会再以数据包的形式发送,这个数据包中就不再包含响应头信息了。
  • off:默认值,响应头信息包含在每一个响应体数据包中。

tcp_nodelay on

  • on:不设置数据发送缓存,即不推迟发送,适合于传输小数据,无需缓存。
  • off:开启发送缓存。若传输的数据是图片等大数据量文件,则建议设置为off

keepalive_timeout 65

设置客户端与Nginx间所建立的长连接的超时时间,时间到达,则连接将会自动关闭。单位为秒。

keepalive_requests 10000

设置一个长连接最多可以发送的的请求数。该值需要在真实环境下测试。

client_body_timeout 10

设置客户端获取Nginx响应的超时时限,即一个请求从客户端发出到接收到Nginx的响应的最长时间间隔,若超时,则认为本次请求失败。