作者:好人森森_195 | 来源:互联网 | 2023-06-03 14:08
http:lenky.info20110910nginx%E7%9A%84%E6%89%A7%E8%A1%8C%E6%A8%A1%E5%9E%8B这一系列的文章还
http://lenky.info/2011/09/10/nginx%E7%9A%84%E6%89%A7%E8%A1%8C%E6%A8%A1%E5%9E%8B/
这一系列的文章还是在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_quit或ngx_terminate(进行要退出或终止?)、ngx_reconfigure(重新加载配置?)等是否被置位并相应的做出处理。当所有信号都处理完时又挂起在函数sigsuspend调用处继续等待新的信号,如此反复,构成监控进程的主要执行体。
工作进程的执行主体与监控进程类似,不过工作进程既然是工作进程,那么它的主要关注点就是与客户端之间的数据可读/可写事件,而不是信号,所以,工作进程的阻塞点是在像select、epoll_wait等这样的函数调用处,以等待发生数据可读/可写事件或是被新收到的信号中断。Nginx的IO复用模型封装得相当不错,当然也非一两句言语能够说得清楚,这将在我们的IO复用模型的统一一章做详细介绍。
转载请保留地址:http://lenky.info/2011/09/10/nginx%e7%9a%84%e6%89%a7%e8%a1%8c%e6%a8%a1%e5%9e%8b/