Nginx源码剖析笔记之进程模型

  Nginx进程模型分为两大类:监控进程(主进程)、工作进程(子进程);

  多进程模型入口函数:ngx_master_process_cycle();主要任务:设置信号处理,然后调用ngx_start_worker_process()生成子进程,这时,主进程主要循环监听信号,而子进程主要循环监听连接。

主进程:在没有收到信号时,用suspend()进入睡眠状态,当有信号到达时,调用相应的信号处理函数ngx_signal_handler().该信号处理函数主要对信号旗标变量做修改,主要的信号处理逻辑代码还是要在主体内进行。在设置完旗标变量后,主体循环中检测有哪些旗标变量被改变,然后做出相应的处理,比如检测到ngx_reap则代表有子进程退出了,要做相关的回收处理,检测到ngx_terminate则代表要强行终止当前进程,检测到ngx_quit则代表要处理完子进程相关工作之后再完成退出工作,检测到ngx_reconfigure则代表要重新加载相关的配置。当处理完相关的信号之后,继续调用suspend进入睡眠,等待信号的到来。

技术分享

void ngx_master_process_cycle(nginx_cycle_t cycle)
{
<span style="white-space:pre">	</span>for(;;){
  <span style="white-space:pre">	</span>  suspend(&set);
    <span style="white-space:pre">	</span>if(...){
     <span style="white-space:pre">	</span> ...
   <span style="white-space:pre">	</span> }
        }
}

这里的set是一个设置好的信号集,类型为sigset_t;

子进程:监听客户端和后端真实服务器的读写事件,进程阻塞点是I/O服用的调用处,比如select,epoll_wait等,真正的事件处理是通过ngx_process_events_and_timer()实现,假设以epoll_wait处理监听,那么该过程就是ngx_process_events_and_timer()->ngx_epoll_process()->epoll_wait();

技术分享


如果Nginx开启了缓存功能,会创建两个相关的cache进程,cache manager process和cache loader process。其中cache manager process进程会嗲用每一个磁盘缓存管理对象的manager函数,比如检查一个缓存是否超过了缓存大小限制,如果超过了缓存限制,则删除缓存。管理进程不接受客户端请求,所以该进程关闭了套接字,并对事件对象设置了超时时间。

对于缓存加载进程则是加载缓存对象到内存,该过程是一次性的,在Nginx启动一段时间(一般是60s)之后加载缓存,然后就自动退出了.


Nginx的进程间通讯:(1)使用socketpair()来创建UNIX进程专用套接字管道,由于socketpair实现的管道是全双工的,并且在进程之间相同的描述符可能代表不同的文件,而用socketpair创建的管道则很好的解决了文件描述符的传递问题,所以用socketpair来实现具有亲缘关系的进程间的通讯是很有效的,但是nginx一般只使用socketpair来传递进程间的资源状态。

(2)共享内存

//nignx一块完整的共享内存结构

typedef ngx_shm_zone_s{
	void * 					data;
	ngx_shm_t				shm;
	nsg_shm—_zone_init_pt	init;
	void * 					tag	//用来标记是创建内存还是使用已有内存
}ngx_shm_zone_t;

//nginx在加载配置文件时,遇到limit_req_zone配置项,
//则将对应的ngx_shm_zone_t结构体变量加入全局链表内
//当全部的配置文件解析完毕后,会初始化该全局链表中所有的共享内存

//ngx_cycle.c

part = &cycle->shared_memory.part;
shm_zone = part->elts;

//遍历整个链表完成共享内存的初始化
for(i = 0;;++i){
	if(ngx_shm_aloc(&shm_zone[i].shm) != NGX_OK){...}
	//alloc指向实际的内存分配接口,可能是mmap也有可能是shmget
	if(ngx_init_zone_pool(cycle,&shm_zone[i]) != NGX_OK){...}
	//pool是ngx的独有内存管理机制
	if(shm_zone[i].init(&shm_zone[i],NULL) != NGX_OK){...}
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。