您的位置:首页 > 运维架构 > Nginx

nginx的master和worker进程间的通信

2015-01-23 00:02 507 查看
本文 主要分析master进程和worker进程之间是如何使用channel来完成通信的。这部分实现的代码主要分布在src/os/unix/ngx_channel.c文件中。master进程将数据传给worker进程,用socketpair创建的通道channel[0]将命令发送给worker进程,告诉worker进程要做什么。而worker进程不需要告诉master进程做什么,是一个单向的通道。

master进程每次发送给worker进程的指令用如下的一个结构来完成封装

typedef struct {
ngx_uint_t command;
ngx_pid_t pid;
ngx_int_t slot;
ngx_fd_t fd;
} ngx_channel_t;四个成员分别表示命令、worker进程的pid、worker进程的slot(在ngx_processes数组中的下标)、文件描述符。
worker进程在收到这个的一个结构数据后,通过判断command来作相应的动作。

master进程用于处理SIGCHLD信号的函数ngx_reap_children中就有向worker进程发送关闭channel的指令

worker进程在调用ngx_worker_process_init函数时,通过ngx_add_channel_event将channel放到epoll事件处理模块中。

if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler)
== NGX_ERROR)
{
/* fatal */
exit(2);
}当收到master进程发过来的命令后,就调用ngx_channel_handler处理,ngx_channel_handler主要做什么呢
switch (ch.command) {

case NGX_CMD_QUIT:
ngx_quit = 1;
break;

case NGX_CMD_TERMINATE:
ngx_terminate = 1;
break;

case NGX_CMD_REOPEN:
ngx_reopen = 1;
break;

case NGX_CMD_OPEN_CHANNEL:

ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
"get channel s:%i pid:%P fd:%d",
ch.slot, ch.pid, ch.fd);

ngx_processes[ch.slot].pid = ch.pid;
ngx_processes[ch.slot].channel[0] = ch.fd;
break;

case NGX_CMD_CLOSE_CHANNEL:

ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
"close channel s:%i pid:%P our:%P fd:%d",
ch.slot, ch.pid, ngx_processes[ch.slot].pid,
ngx_processes[ch.slot].channel[0]);

if (close(ngx_processes[ch.slot].channel[0]) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"close() channel failed");
}

ngx_processes[ch.slot].channel[0] = -1;
break;
}

根据收到的命令类型,采取相应的动作。
整个通信的过程就是如此
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: