转载自Nginx 的执行模型

🔗Nginx 的执行模型

这一系列的文章还是在09年写的,存在电脑里很久了,现在贴出来。顺序也不记得了,看到那个就发那个吧,最近都会发上来。欢迎转载,但请保留链接:http://lenky.info/ ,谢谢。

Nginx 的进程模型和大多数同类服务程序一样,按职责将进程分成监控进程和工作进程两类。在多进程模型下,主进程就充当监控进程,而由主进程fork出来的子进程则充当工作进程;在单进程模型下,主进程就是工作进程,此时没有监控进程。Nginx 的单进程模型比较简单,下面主要分析多进程模型。

分析 Nginx 多进程模型的入口函数为主进程的 ngx_master_process_cycle ,在该函数做完信号处理设置等之后就会调用一个名为 ngx_start_worker_processes 的函数用于 fork 产生出子进程(子进程数目通过函数调用的第二个参数指定),子进程作为一个新的实体开始充当工作进程的角色处理客户端的服务请求;而主进程继续执行 ngx_master_process_cycle 函数,也就是作为监控进程执行主体 for 循环,这是一个死循环,直到进程终止才退出,服务进程基本都是这种写法,所以不用详述,下面先看看这个模型的图示:

执行模型流程图

图示里表现得很明朗,监控进程和工作进程各有一个无限 for 循环,以便进程持续的等待和处理自己负责的事务,直到进程退出。

监控进程的无限 for 循环内有一个关键的 sigsuspend 函数调用,该函数的调用使得监控进程的大部分时间都处于挂起状态,直到监控进程接收到信号为止,当监控进程接收到信号时,调用信号处理函数 ngx_signal_handler 进行处理。我们知道,信号处理函数一般都比较简单,故此在函数 ngx_signal_handler 内执行的动作主要也就是对一些标识字段进行设置,而更具体的处理逻辑仍直接放在 for 循环内,所以该 for 循环接下来的代码就是判断那些标识字段,比如 ngx_reap (有子进程退出?), ngx_quitngx_terminate (进行要退出或终止?), ngx_reconfigure (重新加载配置?)等是否被置位并相应的做出处理。当所有信号都处理完时又挂起在函数 sigsuspend 调用处继续等待新的信号,如此反复,构成监控进程的主要执行体。

工作进程的执行主体与监控进程类似,不过工作进程既然是工作进程,那么它的主要关注点就是与客户端之间的数据可读/可写事件,而不是信号,所以,工作进程的阻塞点是在像 select, epoll_wait 等这样的函数调用处,以等待发生数据可读/可写事件或是被新收到的信号中断。Nginx 的 IO复用模型封装得相当不错,当然也非一两句言语能够说得清楚,这将在我们的IO复用模型章节做详细介绍。

转载请保留地址:http://www.lenky.info/archives/2011/09/48 或 http://lenky.info/?p=48

备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来信讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。