(微信公众号:IT技术精选文摘, 微信号:ITHK01, 欢迎订阅)
同Apache http server的Perfork工作模型类似,Nginx也有master,worker进程的概念。
第一,很显然,启动Nginx,就必须在端口启动监听服务,也就是套接字(ip+port),通常Nginx作为WEB SERVER和反向代理服务器都会在80端口监听。在LINUX上,要开启<1024端口的监听服务,必须用特权身份运行,也就是说master进程应该以root身份启动。
第二,那么master进程主要的职责是什么?
读取并验证配置信息。
创建,绑定,关闭套接字。
启动,终止,维护worker进程的个数。
master负责管理worker进程,这一点好理解,需要注意的是master在处理配置信息这一块。
假设nginx已经启动,我们更改配置文件后reload,如果这个配置文件语法有误,nginx会怎么做?
如果这个配置文件OK,nginx又会怎么做?
如果配置文件有误,reload后,master会提示配置错误,并不会影响请求的处理。
如果配置文件OK,reload后,什么时候生效呢?
Nginx支持热部署
如果主配置文件发生改变,那么并不会立刻影响到WORKER进程,而是MASTER等到WORKER进程的连接请求处理完毕后KILL掉这个WORKER进程,然后重新生成一个WORKER进程,这样这个WORKER进程就将以新的配置启动了。也就是说,老的连接用老的配置,新的连接用新的配置。重新加载配置文件不会中断正在处理的请求。
第三,worker进程是干嘛的?我们应该有多少个Worker进程?每一个Worker进程中有多少个线程?
在Nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环机制进行处理,而每个worker可以并行处理数千个的并发连接和请求。
Worker进程的个数,这个是可以配置的,但是一般而言,个数应该和CPU个数一致性,主要是为了CPU的进程切换。
那么Worker进程是做什么的?
接受,传入并处理来自客户端的连接;
提供反向代理等功能;
第四,worker进程如何处理请求的?
当一个请求来了,那么多个worker进程,谁去处理,还是几个一起处理?如何处理?
首先,要清楚的是,一个请求可以由一个worker进程处理并只能由这个worker进程完全处理。
Nginx在内部其实是维护了一个accept_mutex,其实就是一个锁,确保在某一时刻,一个请求只能被一个worker进程捕获。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。
Nginx采用了异步非阻塞事件驱动的方式来处理请求的,只要我们设置好WORKER进程个数与CPU的亲缘性绑定,那么就能减少CPU在进程间切换所花费的时间以及切换带来的进程的保存/恢复现场,同时,由于Nginx中一个worker里面只有一个线程,也避免了线程的上下文切换。
第五,异步/非阻塞/事件驱动
我们知道,很多请求来了,他们大多需要读写数据,发生IO请求,此时程序就会发生中断,如果此时我们一直等待IO调用结束,才继续工作,那么这种就是阻塞的,那么很显然很多请求来了,都处于等待状态,CPU就将处于空闲状态,为了提供高并发的能力,Nginx采用的是非阻塞的方式。如果发生IO中断,那么你去做你的事情,但是过一段时间来看看IO调用是否结束,这就是非阻塞:你可以做更多的事情,但是你得时不时的检查中断状态,带来的开销也不小。
为了更高效,Nginx利用了LINUX的EPOLL模型(其他系统类似):
EPOLL模型,提供一种事件驱动机制,它可以监控多个事件是否准备好了,如果准备好了,那么就放入EPOLL队列中。这种机制是异步的。通过这样,WORKER进程只需要循环处理EPOLL队列中的请求,我们只需要在请求间不断切换,而这种切换是不需要付出什么代价的,通过这种循环处理已经准备好的请求,从而Nginx可以高效的处理高并发的问题。
(完)
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。