nginx学习 --- 进程管理

初步理解nginx 进程管理nginx

niginx启动后会有一个master和多个worker进程。master进程主要用来管理worker 进程。包括:接受外界信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常状况下),会自动重启新的worker进程。而基本的网络事件,则是在worker进程中处理。多个worker进程之间是对等的,他们的同等竞争来自客户端的请求,但他们之间又是相互对立的。一个请求只能在一个worker进程中处理,一个worker进程不可能处理其余进程的请求。worker进程的个数是能够设置。通常会和机器的CPU个数设置一致(这里的缘由是和nginx的进程模型以及事件处理模型分不开的)。web

nginx 的进程模型以下图:服务器

 

在nginx 启动后,管理nginx 只须要与master 进程通讯就行了。master进程会接受来自外界信号。再根据信号作不一样的事情。因此控制nginx只须要 kill master 进程发信号就能够了(如:kill -HUP pid  则是重启 nginx  )。网络

简单描述一下重启nginx后的进程状态:当重启nginx后,master在接到信号后,会重现加载配置文件,而后启动新的worker进程,并告诉旧的worker进程,他们能够下岗了。新的worker在启动后,就开始接受新的请求,而老的worker就再也不接受请求,而当前进程在全部未处理完的请求处理完成后退出。多线程

那么nginx 内部是如何处理请求的呢? 每一个worker进程都是从master进程fork(叉分)过来的。在master进程里面,先创建号须要listen和socket(listenefd)以后,而后再fork 多个work 进程。全部worker进程的listenfd会在新的链接到来的时候变得可读,为保证只有一个进程处理该链接,全部worker进程在注册listenefd  读事件前抢 accept_mutex , 抢到互斥锁的那个进程注册listenefd读事件,在读事件里调用accept接受该链接。当一个worker进程在accept这个进程后,就开始读取请求,处理请求,产生数据后 ,再返回个客户端,最后才断开链接,这样一个完整的请求就是这样了。并发

上面阐述了nginx进程模型,那么nginx是如何处理事件的。异步

nginx 采用了异步非阻塞的方式来处理请求,即nginx是能够同时处理成千上万个请求的。socket

如今来看一个完整的请求过程。首先,请求过来,要创建链接,而后再接受数据,接受数据后,再发送数据,具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操做,若是不用非阻塞的方式来调用,那就的阻塞调用了,事件没有准备好,那就只能等用,cpu利用率天然就下来了,更不可能高并发了。全部,在nginxl里面,最忌讳阻塞的系统调用了,不要阻塞即非阻塞了。非阻塞就是,事件没有准备好,立刻返回EAGEAIN(eagin),表示事件尚未准备好,过会再来,再检查一下事件,直到事件准备好了为止,虽然不阻塞,但要时不时检查一下事件的状态,因此才有了事件处理机制,具体到系统调用就像 /select/poll/epoll/kqueue 这样的系统调用。他们提供了一种机制,能够同时监控多个事件,调用他们是阻塞的,但能够设置超时时间,在超时时间以内,若是有事件准备好了,就返回。固然线程的个数只有一个,因此同时能处理的请求只有一个,只是在请求间进程不断的切换而已,切换也是由于异步事件未准备好,而主动让出的。这里的切换是没有任何代价。也能够理解为循环多个准备好的事件。与多线程相比,这种事件处理方式是有很大优点的。不须要建立线程,每一个请求占用的内存也很小,处理的事件也很是的轻量级。并发的数量再多也不会致使无谓的资源浪费。函数

对于一个基本的web服务器来讲,事件一般有三种模型,网络事件,信号,定时器。 网络事件经过异步阻塞的方式能够很好的解决。就剩下定时器和信号了。信号 ,特定的信号表明着特殊的意义。信号会中断掉当前程序的运行,在改变状态后,继续执行。若是只是系统调用。则可能会致使系统调用失败。因此信号处理后续学习。定时器,在事件准备的时候,能够设置一个超时时间的,在算出等待的超时时间后进入事件处理状态。因此,当没有事件产生,也没有中断信号时,等待处理的事件会超时 ,这是就有了定时器事件了。这时,nginx 会检查全部的超时事件,讲他们设置为超时,而后在处理网络事件。因此在吃力网络事件的回调函数的时,一般第一件事情就是判断超时,而后处理网络事件。高并发

相关文章
相关标签/搜索