Nginx多进程模型:master与worker进程职责及设置个数的原因

Nginx的多进程模型

Nginx多进程模型:master与worker进程职责及设置个数的原因

Nginx 启动之后,会存在一个 master 进程。同时,还会有多个 worker 进程。

master 进程的主要作用是管理 worker 进程。它会接收来自外界的信号,接着向各个 worker 进程发送信号,同时监控 worker 进程的运行状态,并且还能够启动 worker 进程。

worker 进程的作用是处理来自客户端的请求事件。多个 worker 进程处于对等地位,它们同等地去竞争来自客户端的请求。各个进程相互独立,一个请求只能在一个 worker 进程中进行处理。worker 进程的个数是能够设置的,通常会将其设置为与机器的 CPU 核数相同,这其中的原因和事件处理模型有关系。

Nginx 的进程模型,可由下图来表示:

这种设计带来以下优点:

1) 利用多核系统的并发处理能力

现代操作系统能够支持多核 CPU 架构,这种支持使得多个进程能够各自占用不同的 CPU 核心去进行工作。在 Nginx 当中,所有的 worker 工作进程处于完全平等的地位。这样做提高了网络性能,同时也降低了请求的时延。

2) 负载均衡

多个 worker 工作进程利用进程间通信达成负载均衡。当一个请求到来时,它更有可能被分配到负载较轻的 worker 工作进程去处理。这样在一定程度上提升了网络性能,同时也降低了请求的时延。

3) 管理进程会负责监控工作进程的状态,并负责管理其行为

管理进程不会占用大量系统资源,它主要用于启动、停止、监控或通过其他行为来控制工作进程。其一,这提升了系统的可靠性,倘若 worker 进程出现问题,管理进程能够启动新的工作进程,以避免系统性能下降。这种设计使得 Nginx 服务具有动态定制性较容易实现的特点。

Nginx如何解决惊群现象

什么是惊群现象?

惊群效应指的是多进程或多线程在同时处于阻塞等待同一个事件(处于休眠状态)时,若该事件发生,会唤醒所有等待的进程或线程,但最终只有一个进程或线程能获得该事件的“控制权”来处理该事件,而其他进程或线程获取“控制权”失败,只得重新进入休眠状态,这种现象及由此导致的性能浪费被称作惊群效应。

文中介绍了 Nginx 的多进程模型。文中提到,典型的多进程模型中,多个 worker 进程是对等的。当一个请求到来时,所有进程会同时开始竞争,而最终执行的只有一个。这样必然会导致资源的浪费。

3. 如此一来,当有连接到来时,因为只有一个进程在监听,所以肯定不会出现惊群的问题。

具体做法如下:使用一把进程间锁。在每个进程中,都去尝试获取这把锁。若获取成功,就把监听 socket 加入到 wait 集合中,同时设置超时以等待连接到来。而没有获取到锁的进程,就把监听 socket 从 wait 集合中去除。

事件驱动模型和异步非阻塞IO

我们知道了 Nginx 的多进程模型后了解到,它的工作进程实际上数量并不多。但它为何能获得如此高的并发性能呢?这当然与它采用的事件驱动模型以及异步非阻塞 IO 的方式来处理请求有关。

Nginx 服务器响应和处理 Web 请求的过程,是以事件驱动模型为基础的。它包含着事件收集器、事件发送器以及事件处理器等三部分基本单元。在这个过程中,着重对事件处理器予以关注。而一般情况下,事件处理器存在着以下几种办法:

在编写程序代码时,第三种方式的逻辑比前面两种都更为复杂。大多数网络服务器都采用了第三种方式,并且逐渐形成了所谓的事件驱动处理库。

事件驱动处理库被称作多路 IO 复用方法,其中最常见的有以下三种:一是 select 模型;二是 poll 模型;三是 epoll 模型。

Nginx 同时也支持其他事件模型。

epoll 的帮助在于它提供了一种机制,能够让进程同时对多个并发请求进行处理,并且无需去关心 IO 调用的具体状态。IO 调用由事件驱动模型进行管理。某个工作进程接收到客户端请求后,会调用 IO 进行处理。若不能立即得到结果,就去处理其他请求。工作进程在此期间无需等待响应,可去处理其他事情。当 IO 返回时,epoll 会通知此工作进程。该进程得到通知后,会继续处理未完的请求。

Nginx配置的最佳实践

在生产环境或开发环境里,Nginx通常会代理多个虚拟主机。倘若把所有的配置文件都写在默认的 nginx.conf 中,那么看上去会极为臃肿。所以,建议把每一个虚拟文件单独放置在一个文件夹中,而 Nginx 是支持这样的配置的,具体如下:

http {
    # 省略中间配置
    # 引用该目录下以 .conf 文件结尾的配置
将 /etc/nginx/conf.d/ 目录下的所有以.conf 为后缀的文件包含进来。
}

具体文件配置如:

# Demo
upstream web_pro_testin {
server 的地址为 10.42.46.70,端口为 6003,其中 max_fails 的值为 3,fail_timeout 的值为 20s。
    ip_hash;
}
server {
    listen 80;
server_name 为 web.pro.testin.cn 。
    location / {
将请求转发到 http://web_pro_testin 这个地址。
        proxy_redirect off;
        proxy_set_header Host $host;
设置代理头部 X-Real-IP 为 $remote_addr ;将 X-Real-IP 这个代理头部设置为 $remote_addr ;把 X-Real-IP 这个代理头部设定为 $remote_addr ;让 X-Real-IP 这个代理头部等于 $remote_addr ;使 X-Real-IP 这个代理头部为 $remote_addr 。
    }
    location ~ ^/(WEB-INF)/ {
        deny all;
    }
}

Nginx全量配置参数说明

# 运行用户
user www-data;    
# 启动进程,通常设置成和cpu的数量相等
worker_processes  6;
定义全局错误日志的类型,包含[debug、info、notice、warn、error、crit]
error_log  logs/error.log;
将错误日志记录到 logs/error.log 文件中,并以 notice 级别进行记录。
将错误日志记录到 logs/error.log 文件中,并设置为 info 级别。
# 进程pid文件
pid 是 /var/run/nginx.pid ;
# 工作模式及连接数上限
events {
仅适用于 linux2.6 及以上的内核,能够显著提升 nginx 的性能。
    use   epoll; 
单个后台 worker process 进程可承载的最大链接并发量。
    worker_connections  1024;     
    # 客户端请求头部的缓冲区大小
    client_header_buffer_size 4k;
    # keepalive 超时时间
    keepalive_timeout 60;      
    # 告诉nginx收到一个新连接通知后接受尽可能多的连接
    # multi_accept on;            
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
    # 文件扩展名与文件类型映射表义
将 /etc/nginx/mime.types 包含进来。
    # 默认文件类型
default_type 的类型为 application/octet-stream。
    # 默认编码
    charset utf-8;
    # 服务器名字的hash表大小
server_names_hash_bucket_size 的值为 128 ;
    # 客户端请求头部的缓冲区大小
client_header_buffer_size 的大小为 32k。
    # 客户请求头缓冲大小
设置 large_client_header_buffers 为 4 个,每个大小为 64k 。
    # 设定通过nginx上传文件的大小
    client_max_body_size 8m;
    # 开启目录列表访问,合适下载服务器,默认关闭。
    autoindex on;
sendfile 指令的作用是指定 nginx 是否调用 sendfile 函数(以 zero copy 方式)来输出文件。对于普通应用而言,
必须将其设置为 on。如果是用于下载等应用以及磁盘 IO 重负载应用,那么可以将其设置为 off,这样就能平衡磁盘与网络 I/O 的处理速度。
    sendfile        on;
此选项能对使用 socke 的 TCP_CORK 选项进行允许或禁止操作,且此选项仅在使用 sendfile 时才会被使用。
    #tcp_nopush     on;
    # 连接超时时间(单秒为秒)
    keepalive_timeout  65;
    # gzip模块设置
开启 gzip 压缩输出。
gzip 最小压缩文件大小为 1k。
    gzip_buffers 4 16k;    #压缩缓冲区
gzip_http_version 为 1.0;这是压缩版本(通常默认是 1.1,若前端是 squid2.5 则需使用 1.0)
    gzip_comp_level 2;     #压缩等级
gzip 类型包括 text/plain、application/x-javascript、text/css、application/xml 。
    gzip_vary on;
    # 开启限制IP连接数的时候需要使用
使用 limit_zone 对 crawler 和 $binary_remote_addr 进行限制,限制的大小为 10m。
    # 指定虚拟主机的配置文件,方便管理
    include /etc/nginx/conf.d/*.conf;
    # 负载均衡配置
    upstream mysvr {
        # 请见上文中的五种配置
    }
   # 虚拟主机的配置
    server {
        # 监听端口
        listen 80;
        # 域名可以有多个,用空格隔开
server_name 为 www.jd.com 且 jd.com 。
        # 默认入口文件名称
index 可以是 index.html,也可以是 index.htm 或者 index.php。
        root /data/www/jd;
        # 图片缓存时间设置
位置包含.gif、.jpg、.jpeg、.png、.bmp、.swf 等文件后缀。
            expires 10d;
        }
        #JS和CSS缓存时间设置
        location ~ .*.(js|css)?${
            expires 1h;
        }
        # 日志格式设定
$http_x_forwarded_for 用于记录客户端的 ip 地址。
        #$remote_user:用来记录客户端用户名称;
        #$time_local: 用来记录访问时间与时区;
        #$request: 用来记录请求的url与http协议;
        #$status: 用来记录请求状态;成功是200,
发送给客户端的文件主体内容大小被记录;
$http_referer 用于记录是从哪个页面的链接而访问过来的。
log_format access 表示日志格式。其中包含远程地址 $remote_addr 。还有远程用户 $remote_user 。时间是 $time_local 。请求为 "$request" 。
状态为 $status ,已发送的主体字节数为 $body_bytes_sent ,引用来源为 "$http_referer" 。
“$http_user_agent”以及“$http_x_forwarded_for”
        # 定义本虚拟主机的访问日志
访问日志位于 /usr/local/nginx/logs/host.access.log 且为主日志。
access_log 的路径是 /usr/local/nginx/logs/host.access.404.log ,并将其命名为 log404 。
        # 对具体路由进行反向代理
location 与 connect-controller 有联系。
使用 http://127.0.0.1:88 作为代理传递。
            proxy_redirect off;
设置代理头部 X-Real-IP 为 $remote_addr ;将 X-Real-IP 这个代理头部设置为 $remote_addr ;把 X-Real-IP 这个代理头部设定为 $remote_addr ;让 X-Real-IP 这个代理头部等于 $remote_addr ;使 X-Real-IP 这个代理头部取值为 $remote_addr
后端的 Web 服务器能够借助 X-Forwarded-For 来获取用户的真实 IP。
设置代理头部的 X-Forwarded-For 为 $proxy_add_x_forwarded_for ;将其作为代理的一个设置;通过这个设置来处理请求的转发信息 。
            proxy_set_header Host $host;
            # 允许客户端请求的最大单文件字节数
            client_max_body_size 10m;
            # 缓冲区代理缓冲用户端请求的最大字节数,
            client_body_buffer_size 128k;
让 nginx 阻止 HTTP 应答代码为 400 或者更高的应答。
            proxy_intercept_errors on;
            # nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout 90;
后端服务器数据回传时间意味着在规定时间范围内,后端服务器必须将所有数据传输完毕。 后端服务器需要在规定时间内完成所有数据的传输。 规定时间内,后端服务器要把所有数据传完,这就是后端服务器数据回传时间。 后端服务器在规定时间内必须传完所有数据,此为后端服务器数据回传时间。 后端服务器数据回传时间要求在规定时间内完成所有数据的传输。 规定时间内,后端服务器必须把所有数据都传完,这就是后端服务器数据回传的时间规定。 后端服务器数据回传时间就是要在规定时间内把所有数据传完。 后端服务器需在规定时间内将所有数据传完,这就是其数据回传时间。 后端服务器在规定时间内把所有数据传完,这就是它的数据回传时间。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传的时间要求。 后端服务器数据回传时间就是规定时间内完成所有数据传输的时间。 后端服务器要在规定时间内把所有数据传完,这就是其数据回传的时间。 后端服务器数据回传时间意味着在规定时间内完成所有数据的传输任务。 后端服务器在规定时间内必须把所有数据都传输完毕,这就是它的数据回传时间体现。 规定时间内,后端服务器需将所有数据传完,这就是其数据回传时间的内涵。 后端服务器数据回传时间就是规定时间内把所有数据传完的那个时间。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的具体体现。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的要求。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间段。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键所在。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的重要意义。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的核心内容。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间节点。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的具体指向。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的本质所在。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间范畴。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键要点。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的重要体现。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的核心要点。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间范围。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键之处。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的重要意义所在。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的本质体现。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间维度。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键要素。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的重要体现形式。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的核心关键。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间特性。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键特质。 后端服务器在规定时间内把所有数据传输完毕,这就是它的数据回传时间的重要体现特质。 规定时间内,后端服务器必须完成所有数据的传输,这就是后端服务器数据回传时间的本质特质。 后端服务器数据回传时间就是规定时间内把所有数据都传完的那个时间特征。 后端服务器需在规定时间内把所有数据传完,这就是其数据回传时间的关键特征。 后端服务器在规定时间
            proxy_send_timeout 90;
            # 连接成功后,后端服务器响应的超时时间
            proxy_read_timeout 90;
            # 设置代理服务器(nginx)保存用户头信息的缓冲区大小
            proxy_buffer_size 4k;
设置用于读取应答的缓冲区数目和大小,在默认情况下,其大小也为分页大小,并且根据操作系统的不同,这个大小可能是 4k 或者 8k。
            proxy_buffers 4 32k;
            # 高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;
设置写入 proxy_temp_path 时数据的大小,以预防一个工作进程在传递文件时被阻塞过长时间。
设定缓存文件夹的大小,当这个值被超过时,就会从 upstream 服务器进行传输。
proxy_temp_file 的写入大小为 64k。
        }
        # 动静分离反向代理配置(多路由指向不同的服务端或界面)
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
即将请求传递至 127.0.0.1 的 8080 端口进行处理。
        }
    }
}

Nginx还能做什么解决CORS跨域问题

思路有两个:

适配 PC 或移动设备

根据用户设备的不同,会返回不同样式的站点。以前常使用纯前端的自适应布局,然而,无论是在复杂性方面,还是在易用性方面,它都不如分开编写的好。像我们常见的淘宝、京东等大型网站,它们都没有采用自适应布局,而是采用分开制作的方式,通过判断用户请求的 user-agent 来决定返回 PC 站点还是 H5 站点。

请求限流

Nginx 按请求速率进行限速的模块采用的是漏桶算法。这种算法能够强制确保请求的实时处理速度不会超出所设置的阈值。例如:

http {
限制请求区域,其中包含二进制远程地址,该区域名为 one,大小为 10m,速率为 1r/s 。
    server {
        location /search/ {
使用 limit_req 指令,区域为 one,突发限制为 5,且不延迟;
        }
    }
}      

常见问题Q1:Nginx一般用作什么?

从上述文中了解到 Nginx 在架构体系中的作用,那么配合 Nginx 还能够做哪些事情呢?请给出答案即可。

Q2:为什么要用Nginx?

理解网关的必要性,以及Nginx保证高可用,负载均衡的能力

Q3:为什么Nginx这么快?

如果一个 server 以一个进程负责一个 request 的方式运行,那么进程的数量就等于并发数。很明显,会有许多进程处于等待状态。等待什么呢?其中最多的应该是等待网络传输。

nginx 的异步非阻塞工作方式利用了等待的时间。在需要等待时,这些进程会空闲出来待命。所以表现为少数几个进程就能解决大量的并发问题。

nginx 是怎样被利用的呢?简单来讲:存在 4 个进程。如果采用一个进程负责一个 request 的方式,那么当同时有 4 个 request 进来后,每个进程会负责其中一个 request,直到会话关闭。在此期间,如果有第 5 个 request 进来了。如果 4 个进程都没干完活,就无法及时做出反应。所以,一般会有一个调度进程,每当有新的 request 进来,就会新开一个进程来进行处理。

nginx 并非如此,每有一个 request 进入,就会有一个 worker 进程来进行处理。不过这并非是全程的处理,那会处理到何种程度呢?会处理到可能出现阻塞的地方,例如将 request 转发给上游(后端)服务器,并在此处等待请求返回。这个处理的 worker 不会傻傻地干等着。他会先发送完请求,接着注册一个事件,即“若 upstream 返回了,就通知我,然后我再继续干活”。之后他便去休息了。在这种情况下,如果再有 request 进来,他就能很快按照这种方式进行处理。上游服务器返回后,就会触发这个事件,接着 worker 会来接手,这个 request 才会接着往下走。

因为 web server 的工作性质,所以每个 request 的大部分生命都处于网络传输中,实际上在 server 机器上花费的时间片并不多。这就是几个进程能够解决高并发问题的秘密所在。

总结:事件模型有着其作用,异步非阻塞也有其作用,多进程模型有其作用,再加上细节优化的作用

Q4:什么是正向代理和反向代理

见上文

Q5:Nginx负载均衡的算法有哪些?

见上文

Q6:Nginx如何解决的惊群现象?

见上文

Q7:Nginx为什么不用多线程模型?

深入理解多进程模型的好处,以及异步非阻塞 IO 的好处;同时理解多线程模型中上下文切换存在的劣势。

Q8:Nginx压缩功能有什么坏处吗?

非常耗费服务器的CPU

Q9:Nginx有几种进程模型?

实际上有两种,多进程和单进程,但是实际工作中都是多进程的

最后

大家看完有什么不懂的可以在下方留言讨论.

谢谢你的观看。

觉得文章对你有帮助的话记得关注我点个赞支持一下!

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

53阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

44阅读

php一句话木马,一句话木马ctf

2026年10月05日

48阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

50阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

47阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

42阅读