/* 启动缓存管理进程 */ static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) { ngx_uint_t i, manager, loader; ngx_path_t **path; ngx_channel_t ch; manager = 0; loader = 0; path = ngx_cycle->paths.elts; for (i = 0; i < ngx_cycle->paths.nelts; i++) { /* 判断管理句柄 */ if (path[i]->manager) { manager = 1; } /* 判断加载句柄 */ if (path[i]->loader) { loader = 1; } } if (manager == 0) { return; } /* 启动缓存管理进程 */ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_manager_ctx, "cache manager process", respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; /* 通知其他worker进程和缓存管理进程的通信fd */ ngx_pass_open_channel(cycle, &ch); if (loader == 0) { return; } /* 启动缓存加载进程 */ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_loader_ctx, "cache loader process", respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
/*启动缓存索引重建进程,该进程在整个Nginx服务器运行过程中只存在很短的时间,主要用来遍历磁盘上的缓存数据,在内存中建立数据索引,提高Nginx服务器检索缓存的效率*/ static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) { ngx_uint_t i, manager, loader; ngx_path_t **path; ngx_channel_t ch; manager = 0; loader = 0; path = ngx_cycle->paths.elts; for (i = 0; i < ngx_cycle->paths.nelts; i++) { if (path[i]->manager) { manager = 1; } if (path[i]->loader) { loader = 1; } } if (manager == 0) { return; } /*创建缓存索引管理进程Cache Manager Process,此时respawn=0,所以传入的参数是NGX_PROCESS_JUST_RESPAWN*/ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_manager_ctx, "cache manager process", respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; /*创建进程间通信管道*/ ngx_pass_open_channel(cycle, &ch); if (loader == 0) { return; } /*创建缓存索引管理进程Cache Loader Process,此时respawn=0,所以传入的参数是NGX_PROCESS_JUST_SPAWN*/ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_loader_ctx, "cache loader process", respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; /*创建进程间通信管道*/ ngx_pass_open_channel(cycle, &ch); }
static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) { ngx_uint_t i, manager, loader; ngx_path_t **path; ngx_channel_t ch; manager = 0; loader = 0; path = ngx_cycle->pathes.elts; for (i = 0; i < ngx_cycle->pathes.nelts; i++) { if (path[i]->manager) { manager = 1; } if (path[i]->loader) { loader = 1; } } if (manager == 0) { return; } ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_manager_ctx, "cache manager process", respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); if (loader == 0) { return; } ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, &ngx_cache_loader_ctx, "cache loader process", respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
/*启动工作进程:两个任务,1是设置父子进程通信,2是根据配置循环创建所有的工作进程*/ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); //传递给其他子进程的命令,打开channel ch.command = NGX_CMD_OPEN_CHANNEL; //创建n个worker进程 for (i = 0; i < n; i++) { cpu_affinity = ngx_get_cpu_affinity(i); //[p]fork新进程的具体工作,ngx_worker_process_cycle函数是工作进程要执行的具体工作 ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL, "worker process", type); //全局数组,定义在src/os/unix/ngx_process.c文件中,存储元素类型是ngx_process_t。 //注意,ngx_process_slot在spawn函数中已经赋值完毕,就是当前子进程的位置 ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; //建立通道,用于进程通信 ngx_pass_open_channel(cycle, &ch); } }
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_OPEN_CHANNEL; for (i = 0; i < n; i++) { /*打开主进程和工作进程通信的管道,并fork出子进程,在子进程中运行ngx_worker_process_cycle函数*/ ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; /*循环遍历所有的工作进程信息,将新打开的进程的PID、slot(也就是下标)、channel[0]发送给其他的进程*/ ngx_pass_open_channel(cycle, &ch); } }
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_OPEN_CHANNEL; for (i = 0; i < n; i++) { ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; //父进程将ngx_spawn_process新创建的进程的channel[0] 传递给进程表中的其他进程 ngx_pass_open_channel(cycle, &ch); } }
/* master进程启动n个子进程 */ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_OPEN_CHANNEL; /* 创建n个worker进程 */ for (i = 0; i < n; i++) { /* ngx_worker_process_cycle用来初始化worker进程的主循环 */ ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; /* 将子进程的0通道通知其他在前创建的进程,1通道是接收信息的 */ ch.fd = ngx_processes[ngx_process_slot].channel[0]; /* 把创建的子进程的相关信息通知前面已经生成的子进程, * 注意这里是父进程把刚创建的子进程的相关信息发送给其他子进程, * 而不是子进程自己发送的 */ ngx_pass_open_channel(cycle, &ch); } }
// 被ngx_master_process_cycle()调用 // 启动worker进程,数量由配置决定,即worker_processes指令 // 调用时传递的是#define NGX_PROCESS_RESPAWN -3 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ngx_memzero(&ch, sizeof(ngx_channel_t)); // unix channel ch.command = NGX_CMD_OPEN_CHANNEL; for (i = 0; i < n; i++) { // os/unix/ngx_process.c产生进程,执行ngx_worker_process_cycle // 创建的进程都在ngx_processes数组里 // 定义在os/unix/ngx_process.c // ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); // 设置channel信息 ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; // 建立channel,用于进程间通信 ngx_pass_open_channel(cycle, &ch); } }
static void ngx_start_session_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) { ngx_channel_t ch; if (!cycle->session_enabled) { return; } ngx_spawn_process(cycle, ngx_session_manager_process_cycle, &ngx_session_manager_ctx, "session manager process", respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
static void ngx_start_ip_blacklist_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) { ngx_channel_t ch; if (!cycle->ip_blacklist_enabled) { /* ip blacklist not enabled, don't start the helper */ return; } ngx_spawn_process(cycle, ngx_ip_blacklist_manager_process_cycle, &ngx_ip_blacklist_manager_ctx, "IP blacklist manager process", respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); // 传递给子进程的命令 ch.command = NGX_CMD_OPEN_CHANNEL; for (i = 0; i < n; i++) { // fork子进程 ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); // 初始化channel,ngx_process_slot在ngx_spawn_process中已经赋值 ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); } }
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) { ngx_int_t i; ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ch.command = NGX_CMD_OPEN_CHANNEL; for (i = 0; i < n; i++) { cpu_affinity = ngx_get_cpu_affinity(i); ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); } }
static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle) { ngx_int_t i, n; ngx_uint_t live; ngx_channel_t ch; ngx_core_conf_t *ccf; ngx_memzero(&ch, sizeof(ngx_channel_t)); ch.command = NGX_CMD_CLOSE_CHANNEL; ch.fd = -1; live = 0; for (i = 0; i < ngx_last_process; i++) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "child: %d %P e:%d t:%d d:%d r:%d j:%d", i, ngx_processes[i].pid, ngx_processes[i].exiting, ngx_processes[i].exited, ngx_processes[i].detached, ngx_processes[i].respawn, ngx_processes[i].just_spawn); if (ngx_processes[i].pid == -1) { continue; } if (ngx_processes[i].exited) { if (!ngx_processes[i].detached) { ngx_close_channel(ngx_processes[i].channel, cycle->log); ngx_processes[i].channel[0] = -1; ngx_processes[i].channel[1] = -1; ch.pid = ngx_processes[i].pid; ch.slot = i; for (n = 0; n < ngx_last_process; n++) { if (ngx_processes[n].exited || ngx_processes[n].pid == -1 || ngx_processes[n].channel[0] == -1) { continue; } ngx_log_debug3(NGX_LOG_DEBUG_CORE, cycle->log, 0, "pass close channel s:%i pid:%P to:%P", ch.slot, ch.pid, ngx_processes[n].pid); /* TODO: NGX_AGAIN */ ngx_write_channel(ngx_processes[n].channel[0], &ch, sizeof(ngx_channel_t), cycle->log); } } if (ngx_processes[i].respawn && !ngx_processes[i].exiting && !ngx_terminate && !ngx_quit) { if (ngx_spawn_process(cycle, ngx_processes[i].proc, ngx_processes[i].data, ngx_processes[i].name, i) == NGX_INVALID_PID) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "could not respawn %s", ngx_processes[i].name); continue; } ch.command = NGX_CMD_OPEN_CHANNEL; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); live = 1; continue; } if (ngx_processes[i].pid == ngx_new_binary) { ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_rename_file((char *) ccf->oldpid.data, (char *) ccf->pid.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_rename_file_n " %s back to %s failed " "after the new binary process \"%s\" exited", ccf->oldpid.data, ccf->pid.data, ngx_argv[0]); } ngx_new_binary = 0; if (ngx_noaccepting) { ngx_restart = 1; ngx_noaccepting = 0; } } if (i == ngx_last_process - 1) { ngx_last_process--; } else { ngx_processes[i].pid = -1; } } else if (ngx_processes[i].exiting || !ngx_processes[i].detached) { live = 1; } } return live; }