暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

浅谈Nginx的多进程模型

Nginx是互联网企业使用最为广泛的轻量级高性能Web服务器,其特点是占用内存少、并发能力强。Nginx之所以被大家所喜爱,除了其高性能外,还有其优雅的系统架构。与Memcached的经典多线程模型相比,Nginx是经典的多进程模型。



Nginx的应用特点

在介绍Nginx应用特点前,首先介绍一下IO密集型和计算密集型。IO密集型就是指IO占主要任务,计算量很小,比如请求网页,读写文件;计算密集型就是指CPU计算占主要任务,CPU一直处于满负荷状态,比如大循环计算。


而Nginx本质上是一个Web Server,Web Server的作用是解析HTTP请求返回静态数据或者把一些动态请求托付给其它server端程序。基于Nginx的这样的工作性质,决定每个request的大部份生命都是在网络传输中,实际上花费在server机器上的时间片不多。


因此Nginx属于网络IO密集型应用,不算是计算密集型。基于这样的特点,才有可能实现多进程解决高并发的设计方案。换一个角度看,多进程解决高并发的设计方案,是应对IO密集型的有效手段之一。所以在开发实践中,遇到类似的场景可以考虑使用类似的解决方案来应对。



Nginx的多进程模型

Nginx采用的是经典的master-worker模型的多进程模型,即一个master进程管理一个或者多个worker进程。基本的事件处理都在worker进程,master进程负责一些全局初始化,以及对worker进程的管理,如下图所示。



master进程主要有以下4个主要功能:

(1) 接收来自外界的信号;

(2) 向各个worker进程发送信号;

(3) 监控worker的运行状态;

(4) 当worker进程退出后,自动重启新的worker进程。


worker进程主要处理网络事件,多个worker进程之间是对等的,每个进程处理请求的机会也是一样的。


Nginx采用异步非阻塞的方式处理网络事件,具体过程如下图所示。



master进程先建好需要监听的socket后,再fork出多个worker进程,这样每个worker进程都可以去接收这个socket。当一个client连接到来时,所有的worker进程都会收到通知,但只有一个可以accept成功。这里Nginx提供了一个共享锁accept_mutex,虽然所有的worker都会收到通知,但只有一个进程抢到锁,其它失败,成功的worker进程接收请求。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接。


当运行过程中,如果worker进程出现异常,master会对worker进行重启。重启时会先启动新的worker进程,然后向老的worker发送信号。新的worker启动后,就开始接收新的请求;而老的worker在收到信号后不再接收请求,将当前进程中所有未处理完的请求处理完成后,再退出。这样最大程度的满足可用性要求。



多进程单线程与单进程多线程

其实,多进程模型的目的是想尽可能的利用CPU,减少空闲时间,特别是多核环境。这样就不得不提到单进程多线程模型。


简单来看,二者最直观的区别是CPU同时在多个进程上工作还是多个线程上工作。从性能上说,多进程的CPU切换是一个进程到另一个进程,而多线程的CPU切换是在同一个进程内,显然进程间的切换消耗更大。从数据共享上说,同一进程下更容易共享数据。


另一方面,多进程带来了隔离保护机制,一个进程的错误不会带来整个程序的崩溃,而master进程完全不涉及业务,使得它可以被安全隔离。但单进程多线程下,一个线程错误有可能带来整个进程的问题。当然也可以用守护进程来重启,但是重启过程服务是不可用的。另外,单进程多线程的数据共享也带来了太多的锁和全局变量,这些内容在开发过程中也导致代码复杂度高、难以控制稳定性、死锁等问题。


综上,本文结合Nginx的应用特点,介绍了Nginx的多进程模型,并简单比较了多进程单线程与单进程多线程模型的异同与特点,希望为大家在后续开发设计中提供有益的启发。


作者 | 杨    成

视觉 | 王朋玉

统筹 | 郑    洁

文章转载自中国光大银行科技创新实验室,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论