nginx高并发优化之事件驱动模块设置

时间:2022-11-04 12:47:05

一、概述

events {
use epoll;
worker_connections 65535;
}

二、说明

1、use epoll;
设置事件驱动模型使用epoll。事件驱动模型有select、poll、poll等。
select先创建事件的描述符集合,对于一个描述符,可以关注其上面的Read事件、Write事件以及Exception事件,所以要创建三类事件描述符
集合,分别用来处理Read事件的描述符、Write事件的描述符、Exception事件的描述符,然后调用底层的select()函数,等待事件发生,
轮询所有事件描述符集合的每一个事件描述符,检查是否有事件发生,有的话就处理。select效率低,主要是轮询效率低,而且还要分别轮
询三个事件描述符的集合。
poll方法与select类似,都是先创建一个关注事件的描述符集合,再去等待这些事件发生,然后再轮询描述符集合,检查有无事件发生,如
果有,就去处理。不同点是poll为Read事件、Write事件以及Exception事件只创建一个集合,在每个描述符对应的结构上分别设置Read
事件、Write事件以及Exception事件。最后轮询的时候,可以同时检察权这三个事件是否发生。可以说,poll库是select库的优化实现。
epoll是Nginx支持的高性能事件驱动库之一。是公认的非常优秀的事件驱动模型。和poll库跟select库有很大的不同,最大区别在于效率。
我们知道poll库跟select库都是创建一个待处理的事件列表,然后把这个列表发给内核,返回的时候,再去轮询检查这个列表,以判断事
件是否发生。这样在描述符多的应用中,效率就显得比较低下了。一种比较好的方式是把列表的管理交由内核负责,一旦某种事件发生,
内核就把发生事件的描述符列表通知给进程,这样就避免了轮询整个描述符列表。首先,epoll库通过相关调用同志内核创建一个有N个描
述符的事件列表,然后给这些描述符设置所关注的事件,并把它添加到内核的事件列表中去。完成设置以后,epoll库就开始等待内核通知
事件发生了,某一事件发生后,内核讲发生事件的描述符列表上报给epoll库,得到事件列表的epoll库,就可以进行事件处理了。epoll库
在linux平台是高效的,它支持一个进程打开大数目的事件描述符,上限是系统可以打开文件的最大数目;同时,epoll库的IO效率不随描
述符数量的增加而线性下降,因为它只会对内核上报的活跃的描述符进行操作。

2、worker_connections 65535;
#单个进程允许的客户端最大连接数
设置一个进程理论允许的最大连接数,理论上越大越好,但不可以超过worker_rlimit_nofile的值。还有个问题,linux系统中有个指令
open file resource limit,它设置了进程可以打开的文件句柄数量,可以用下面的指令查看你的linux系统中open file resource
limit指令的值,cat /proc/sys/fs/file-max可以将该指令设置为23900251
echo "2390251" > /proc/sys/fs/file-max;
sysctl -p
#nginx的最大连接数[worker_connections]×[worker_processes]

3、accept_mutex
默认off
#设置Nginx网络连接序列化
这个牵扯到《UNIX网络编程》第一卷中提到的“惊群”问题(Thundering herd problem),大致意思是当某一时刻只有一个网络连接到来时,
多个睡眠进程会被同时叫醒,但只有一个进程可获得连接,如果每次唤醒的进程数目太多,会影响一部分系统性能。在Nginx服务器的多进程
下,就可能出现这个问题,为了解决这个问题,Nginx配置了包含这样一条指令accept_mutex,当其设置为开启的时候,将会对多个Nginx进
程接受连接进行序列化,防止多个进程对连接的争抢。当服务器连接数不多时,开启这个参数会让负载有一定程度的降低。但是当服务器的
吞吐量很大时,为了效率,请关闭这个参数;并且关闭这个参数的时候也可以让请求在多个worker间的分配更均衡。所以我们设置
accept_mutex off;

4、multi_accept
默认off
如果multi_accept禁用,一个worker进程将一次接受一个新连接。否则,worker进程将一次接受所有新连接。
multi_accept指令使得NGINX worker能够在获得新连接的通知时尽可能多的接受连接。 此指令的作用是立即接受所有连接放到监听队列中
。 如果指令被禁用,worker进程将逐个接受连接。
让nginx worker进程尽可能多地接受请求。它的作用是让worker进程一次性地接受监听队列里的所有请求,然后处理。
如果multi_accept的值设为off,多个worker按并行方式来处理连接,也就是一个连接会唤醒所有的worker,直到连接分配完毕,没有取得
连接的继续休眠。
否则的话,多个worker按串行方式来处理连接,也就是一个连接只有一个worker被唤醒,其他的处于休眠状态,这个工作进程将同时接受所
有的新连接。
默认Nginx没有开启multi_accept(也有说法默认开启,可能存在版本差异)。如果web服务器面对的是一个持续的请求流,那么启用
multi_accept可能会造成worker进程一次接受的请求大于worker_connections指定可以接受的请求数。这就是overflow,这个overflow
会造成性能损失,overflow这部分的请求不会受到处理。