static void ngx_session_manager_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_session_manager_ctx_t *ctx = data; void *ident[4]; ngx_event_t ev; cycle->connection_n = 512; ngx_process = NGX_PROCESS_HELPER; ngx_worker_process_init(cycle, 0); ngx_close_listening_sockets(cycle); ngx_memzero(&ev, sizeof(ngx_event_t)); ev.handler = ctx->handler; ev.data = ident; ev.log = cycle->log; ident[3] = (void *) -1; ngx_use_accept_mutex = 0; ngx_setproctitle(ctx->name); ngx_add_timer(&ev, ctx->delay); for ( ;; ) { if (ngx_terminate || ngx_quit) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); exit(0); } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } ngx_process_events_and_timers(cycle); } }
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_int_t worker = (intptr_t) data; ngx_uint_t i; ngx_connection_t *c; ngx_process = NGX_PROCESS_WORKER; ngx_worker_process_init(cycle, worker); ngx_setproctitle("worker process"); #if (NGX_THREADS) { ngx_int_t n; ngx_err_t err; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_threads_n) { if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle) == NGX_ERROR) { /* fatal */ exit(2); } err = ngx_thread_key_create(&ngx_core_tls_key); if (err != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, err, ngx_thread_key_create_n " failed"); /* fatal */ exit(2); } for (n = 0; n < ngx_threads_n; n++) { ngx_threads[n].cv = ngx_cond_init(cycle->log); if (ngx_threads[n].cv == NULL) { /* fatal */ exit(2); } if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid, ngx_worker_thread_cycle, (void *) &ngx_threads[n], cycle->log) != 0) { /* fatal */ exit(2); } } } } #endif for ( ;; ) { if (ngx_exiting) { c = cycle->connections; for (i = 0; i < cycle->connection_n; i++) { /* THREAD: lock */ if (c[i].fd != -1 && c[i].idle) { c[i].close = 1; c[i].read->handler(c[i].read); } } if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events_and_timers(cycle); if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { ngx_close_listening_sockets(cycle); ngx_exiting = 1; } } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } }
/*[p] 工作进程要执行的具体工作*/ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_uint_t i; ngx_connection_t *c; ngx_process = NGX_PROCESS_WORKER; //初始化worker进程 ngx_worker_process_init(cycle, 1); //[p]设置工作进程标题 ngx_setproctitle("worker process"); #if (NGX_THREADS) { ngx_int_t n; ngx_err_t err; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_threads_n) { if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle) == NGX_ERROR) { /* fatal */ exit(2); } err = ngx_thread_key_create(&ngx_core_tls_key); if (err != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, err, ngx_thread_key_create_n " failed"); /* fatal */ exit(2); } for (n = 0; n < ngx_threads_n; n++) { ngx_threads[n].cv = ngx_cond_init(cycle->log); if (ngx_threads[n].cv == NULL) { /* fatal */ exit(2); } if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid, ngx_worker_thread_cycle, (void *) &ngx_threads[n], cycle->log) != 0) { /* fatal */ exit(2); } } } } #endif for ( ;; ) { //ngx_exiting是当收到master的quit命令(SIGQUIT信号)后,设置为1,然后等待其他资源退出 if (ngx_exiting) { c = cycle->connections; // worker进程退出前,先处理完每个connection上已经发生的事件 for (i = 0; i < cycle->connection_n; i++) { /* THREAD: lock */ if (c[i].fd != -1 && c[i].idle) { c[i].close = 1; c[i].read->handler(c[i].read); } } //定时器超时则退出worker; 处理完所有事件,worker进程退出 if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); // 这里是worker进程处理事件的核心。 ngx_process_events_and_timers(cycle); //收到shutdown命令(SIGINT信号)则worker直接退出 if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } //收到quit命令(SIGQUIT信号) if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { //关闭socket,然后设置退出标志 ngx_close_listening_sockets(cycle); ngx_exiting = 1; } } //收到master重新打开log的命令,worker进程收到了SIGUSR1信号 if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } }
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_int_t worker = (intptr_t) data; ngx_uint_t i; ngx_connection_t *c; ngx_process = NGX_PROCESS_WORKER; ngx_worker = worker; ngx_worker_process_init(cycle, worker); ngx_setproctitle("worker process"); for ( ;; ) { if (ngx_exiting) { c = cycle->connections; for (i = 0; i < cycle->connection_n; i++) { /* THREAD: lock */ if (c[i].fd != -1 && c[i].idle) { c[i].close = 1; c[i].read->handler(c[i].read); } } ngx_event_cancel_timers(); if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events_and_timers(cycle); if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { ngx_close_listening_sockets(cycle); ngx_exiting = 1; } } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } }
// 传递给ngx_spawn_process(),是worker进程的核心功能 // data实际上是进程号, (void *) (intptr_t) i static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { // 把data再转换为进程序号 ngx_int_t worker = (intptr_t) data; ngx_uint_t i; ngx_connection_t *c; // 设置进程状态 ngx_process = NGX_PROCESS_WORKER; // nginx 1.9.x //ngx_worker = worker; // 读取核心配置,设置cpu优先级,core dump信息,unix运行的group/user // 切换工作路径,根据pid设置随机数种子 // 调用所有模块的init_process,让模块进程初始化 ngx_worker_process_init(cycle, worker); // 设置进程名字 ngx_setproctitle("worker process"); // 无限循环,处理事件和信号 for ( ;; ) { // 进程正在退出,即quit // 收到了-s quit,关闭监听端口后再停止进程(优雅关闭) if (ngx_exiting) { c = cycle->connections; for (i = 0; i < cycle->connection_n; i++) { /* THREAD: lock */ if (c[i].fd != -1 && c[i].idle) { c[i].close = 1; c[i].read->handler(c[i].read); } } // 取消定时器,调用handler处理 ngx_event_cancel_timers(); // 定时器红黑树为空,即已经没有任何事件 // 否则表示还有事件未处理,暂不退出 if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); // 调用所有模块的exit_process,进程结束hook // 内部直接exit(0)退出 ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); // 处理事件的核心函数, event模块里 // 处理socket读写事件和定时器事件 // 获取负载均衡锁,监听端口接受连接 // 调用epoll模块的ngx_epoll_process_events // 然后处理超时事件和在延后队列里的所有事件 // nginx大部分的工作量都在这里 ngx_process_events_and_timers(cycle); // 收到了-s stop,直接停止进程 if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); // 调用所有模块的exit_process,进程结束hook // 内部直接exit(0)退出 ngx_worker_process_exit(cycle); } // 收到了-s quit,关闭监听端口后再停止进程(优雅关闭) if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); // 改进程名字 ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { // in ngx_connection.c // 遍历监听端口列表,逐个删除监听事件 // 不再接受新的连接请求 ngx_close_listening_sockets(cycle); // 设置ngx_exiting标志,继续走循环 // 等所有事件都处理完了才能真正退出 ngx_exiting = 1; } } // 收到了-s reopen,重新打开文件 if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } // 无限循环,处理事件和信号 }
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_int_t worker = (intptr_t) data; ngx_process = NGX_PROCESS_WORKER; ngx_worker = worker; /* worker进程的初始化工作 */ ngx_worker_process_init(cycle, worker); ngx_setproctitle("worker process"); /* worker进程的主循环 */ for ( ;; ) { /* 如果通过通道接受到退出的命令,则worker进程会退出, * 注意这里的退出,是会有序的释放资源 */ if (ngx_exiting) { ngx_event_cancel_timers(); if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); /* 网络事件处理函数 */ ngx_process_events_and_timers(cycle); if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); /* 设置进程的title */ ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { ngx_exiting = 1; ngx_close_listening_sockets(cycle); ngx_close_idle_connections(cycle); } } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } }