nginx的main启动:初始化master进程信息

- 解析命令:ngx_get_options()
- 解析启动传入的参数argv:
- 若是有p,则初始化前缀路径全局变量 ngx_prefix
- 若是有c,则初始化配置文件全局变量 ngx_conf_file
- 若是有g,则初始化全局指令全局变量 ngx_conf_params
- 若是有s,则初始化信号全局变量 ngx_signal
- ngx_process = NGX_PROCESS_SIGNALLER
- ngx_signal=stop或quit或reopen或reload
- 初始化时间:ngx_time_init()
- 初始化ngx_cached_err_log_time的长度
- 初始化ngx_cached_http_time
- 初始化ngx_cached_http_log_time
- 初始化ngx_cached_http_log_iso8601
- 初始化ngx_cached_syslog_time
- 初始化ngx_cached_time的地址
- 调用全局变量 ngx_time_update=&cached_time[slot],初始化时间:
- 获取ngx_time_lock锁
- 获取linux的时间timeval,解析成ngx_current_msec
- 初始化cached_time的值
- 释放ngx_time_lock锁
- 若是有NGX_PCRE,则初始化prel的正则功能能:ngx_regex_init()
- 初始化日志:ngx_log_init()
- 打开log日志,若是日志不存在。则将日志指向stderr
- 若是有NGX_OPENSSL,初始化SSL:ngx_ssl_init()
- 初始化内存池1024B:ngx_create_pool()
- 保存命令:ngx_save_argv()
- 保存命令行的数据到ngx_cycle_s中:ngx_process_options()
- 将前缀:ngx_prefix添加到ngx_cycle_s.conf_prefix
- 将命令行配置文件:ngx_conf_file添加到ngx_cycle_s.conf_file
- 将全局指令ngx_conf_params添加到ngx_cycle_s.conf_param
- 设置进程环境:ngx_os_init()
- 如内存页面大小 ngx_pagesize , ngx_cacheline_size , 最大链接数 ngx_max_sockets 等
- 初始化CRC表:ngx_crc32_table_init()
- 初始化slab数据:ngx_slab_sizes_init()
- 初始化继承的套接字链接池:ngx_add_inherited_sockets()
- 解析环境变量 NGINX_VAR = "NGINX" 中的 sockets,并保存至 ngx_cycle.listening 数组;
- 设置继承套接字 ngx_inherited = 1;
- 调用 ngx_set_inherited_sockets() 逐一对 ngx_cycle.listening 数组中的 sockets 进行设置;
- 设置监听文件符的sockaddr空间
- 设置监听文件符的socklen空间
- 经过getsockname()获取监听套接字的地址
- 经过getsockname()获取监听套接字的地址
- ngx_preinit_modules()
- 初始化每一个 module 的 index,并计算 ngx_max_module
- 初始化master的ngx_cycle_s :ngx_init_cycle()
- 更新 timezone 和 time
- 建立内存池
- 给 cycle 指针分配内存
- 保存安装路径,配置文件,启动参数等
- 初始化文件句柄
- 初始化共享内存
- 初始化链接队列
- 保存 hostname
- 调用各 NGX_CORE_MODULE 的 create_conf 方法,建立模块的上下文配置内存空间
- 解析配置文件,替换模块的上下文配置
- 调用各NGX_CORE_MODULE的init_conf方法,检测模块的上下文配置是否设置彻底,没有设置的参数设置为默认值
- 打开新的文件句柄
- 建立共享内存
- 处理监听socket
- 建立socket并监听:ngx_open_listening_sockets(cycle)
- for i<5
- for cycle->listening.elts
- 非继承
- 建立socket
- 设置socket套接字为可重复使用
- bind套接字到地址上
- listen监听套接字,将其放到backlog上
- end for cycle->listening.elts
- end for
- 关闭不须要的socket
- 关闭不须要的共享内存
- 关闭不须要的文件
- ngx_init_modules()-->模块初始化函数init_module()
- 如有信号,则进入 ngx_signal_process() 处理
- 调用 ngx_init_signals() 初始化信号,主要完成信号处理程序的注册
- 进入主循环:ngx_single_process_cycle() 和 ngx_master_process_cycle()
主循环初始化后的运行:ngx_master_process_cycle
- 阻塞nginx的消息
- 设置进程名称
- 启动工做进程:ngx_start_worker_processes
- 循环
- 调用:ngx_spawn_process() 建立 "worker process":
- 经过socketpair() 获取UNIX域套接字传输管道,即管道
- 设置管道为非阻塞模式:ngx_nonblocking()
- 设置管道为异步模式:ioctl()
- 设置异步 I/O 的全部者:fcntl()
- fork()启动子进程,并执行进程的初始化回调函数:proc(cycle, data)
- 即 ngx_worker_process_cycle
- 设置 ngx_processes[s] 相关属性
- 通知以前的work进程新work进程建立完毕 ngx_pass_open_channel(cycle, &ch);
- 经过管道发送消息:ngx_write_channel()-->sendmsg()
- 结束循环
- 启动cache管理进程:ngx_start_cache_manager_processes
- 调用:ngx_spawn_process() 建立 "cache manager process":
- 经过socketpair() 获取UNIX域套接字,即管道
- 设置管道为非阻塞模式:ngx_nonblocking()
- 设置管道为异步模式:ioctl()
- 设置异步 I/O 的全部者:fcntl()
- fork()启动子进程,并执行进程的初始化回调函数:proc(cycle, data)
- 即 ngx_cache_manager_process_cycle
- 设置 ngx_processes[s] 相关属性
- work建立成功,通知以前的全部work进程新进程建立完毕 ngx_pass_open_channel(cycle, &ch);
- 经过管道发送消息:ngx_write_channel()-->sendmsg()
- 循环等待信号:
- setitimer()阻塞一段时间等待进程启动
- sigsuspend()阻塞等待新号
- ngx_time_update()刷新新时间
- 若是有 worker 进程由于 SIGCHLD 信号退出了,则重启 worker 进程
- master 进程退出。若是全部 worker 进程都退出了,而且收到 SIGTERM 信号或 SIGINT 信号或 SIGQUIT 信号等,master 进程开始处理退出
- 处理ngx_terminate、ngx_quit、ngx_reconfigure、ngx_restart、ngx_reopen、ngx_change_binary、ngx_noaccept信号
工做进程的运行流程(初始化回调函数):ngx_worker_process_cycle
work进程的cycle不须要在初始化ngx_listen_t信息:socket、bind、listen。只须要绑定一个读的处理函数linux
- ngx_worker_process_init()初始化进程信息
- 初始化环境变量
- 设置进程优先级
- 设置文件句柄数量限制
- 设置 core_file 文件
- 用户组设置
- cpu 亲和度设置
- 设定工做目录
- 设置随机种子数
- 初始化监听状态
- 调用各模块的init_process方法进行初始化(这里会初始化 epoll)
- 关闭其它进程的fd[1],保留别人的fd[0]用于互相通讯。关闭本身的fd[0],保留本身的fd[1]接收master进程的消息。
- 监听管道读事件:ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler)
- 获取链接文件描述符:ngx_get_connection()
- 初始化读写内存
- 添加管道读事件回调函数:ngx_channel_handler 到读事件NGX_READ_EVENT
- 经过 recvmsg() 阻塞获取master进程发送的消息
- 这里用来接受master进程的发送启动成功的消息
- 循环执行事件和监听信号
- ngx_process_events_and_timers()执行事件
- ngx_trylock_accept_mutex 当获取到标志位后才进行 accept 事件注册。
- 执行进程事件ngx_process_events(cycle, timer, flags)。将epoll准备好的读写放到nginx的事件列表中
- 释放 accept_mutex 锁。
- 处理定时器事件
- ngx_event_process_posted(cycle, &ngx_posted_accept_events) 处理 ngx_posted_events和ngx_posted_accept_events 队列的事件
- 监听ngx_terminate、ngx_quit、ngx_reopen信号
进程事件处理函数:执行回调函数ngx_process_events
暂无
acceptd处理函数:ngx_event_process_posted
void
ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted)
{
ngx_queue_t *q;
ngx_event_t *ev;
while (!ngx_queue_empty(posted)) {
q = ngx_queue_head(posted);
ev = ngx_queue_data(q, ngx_event_t, queue);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"posted event %p", ev);
ngx_delete_posted_event(ev);//删除事件
ev->handler(ev);//事件处理
}
}
- 全局事件队列:
- ngx_posted_accept_events: 接受事件队列
- ngx_posted_events: 读、写事件丢列
- NGX_READ_EVENT:读类型nginx事件
- NGX_POST_EVENTS:写类型nginx事件