Nginx启动初始化过程(一)
Nginx的启动初始化在src/core/nginx.c的main函数中完成,当然main函数是整个Nginx的入口,除了完成启动初始化任务以外,也必定是所有功能模块的入口之处。Nginx的初始化工作主要围绕一个类型为ngx_cycle_t类型的全局变量(cycle)展开。下面具体看一下main函数为Nginx的启动过程做了哪些初始化方面的事情。(以下代码段都是顺序从main函数中摘取出来的, 对照源码阅读可能更易明白)
main函数做的第一件事情就是对参数选项进行处理,和普通的Linux程序如出一辙,如下:
if (ngx_get_options(argc, argv) != NGX_OK) { return 1; }
Nginx用此函数对参数选项进行解析,从而采取相应的动作,比如:显示版本、测试配置等功能。其实此函数实现的很简陋,远没有Linux提供的getopt()那么强悍,但却可以达到跨平台的目的。
ngx_time_init(); #if (NGX_PCRE) ngx_regex_init(); #endif ngx_pid = ngx_getpid(); log = ngx_log_init(ngx_prefix); if (log == NULL) { return 1; }
上述几行代码的功能如其名,主要完成Nginx在时间和日志等方面的初始化工作。
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK){ return 1; }
将命令行参数保存到ngx_os_argv、ngx_argc以及ngx_argv这几个全局的变量中。这算是一个备份存储,方便以后master进程做热代码替换之用。
if (ngx_os_init(log) != NGX_OK) {
return 1;
}
完成操作系统的一些信息获取,如内存页面大小、系统限制资源等信息;所有的这些资源都将会被保存在对应的全局变量中,因此后续访问将会很便利。
if (ngx_crc32_table_init() != NGX_OK) {
return 1;
}
初始化一个做循环冗余校验的表,由此可以看出后续的循环冗余校验将采用高效的查表法。crc算法此处就不做分析,网上一堆一堆的相关资料,有兴趣的同学可以了解。
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return 1;
}
通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。在NGINX环境变量中,每个socket中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1。
ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; }
额!!!这个循环中的ngx_modules数组好像没见定义,难不成是火星来的?当然不是,如其名,这就是一个存储所有模块的信息,包括自己开发的模块都会放到这个数组中,而这个神秘的数组却是在自动编译的时候生成的,位于objs/ngx_modules.c文件中。这个循环的目的是清晰可见的――对所有模块进行索引编号,方便以后访问;同时借助ngx_max_module对所有模块进行了一次点数,确定究竟有多少模块。而神秘数组ngx_modules的长相大概如下:
ngx_module_t *ngx_modules[] = { &ngx_core_module, &ngx_errlog_module, &ngx_conf_module, &ngx_events_module, &ngx_event_core_module, &ngx_epoll_module, &ngx_openssl_module, &ngx_http_module, 。。。 };
cycle = ngx_init_cycle(&init_cycle);
这里将会初始化很多的东东到全局变量cycle中,是Nginx启动初始化的核心之处。ngx_init_cycle函数的过程比较多,放下一篇blog中逐段分析。
if (ngx_init_signals(cycle->log) != NGX_OK) {
return 1;
}
注册一堆信号处理程序,需要注册的信号及相应的信号处理函数被放在一个类型为ngx_signal_t的数组signals中。数组定义在src/os/unix/ngx_process.c中。ngx_signal_t结构类型定义了信号值,信号名字,信号对应动作名以及信号处理函数。
if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
ngx_daemon肯定就是用来实现守护进程的函数了,此处就不多废话了,有需要写server程序的,可以直接copy这段代码实现守护进程。
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
玩过Nginx的人都知道,Nginx启动后有一个记录进程id的文件,这个文件里面就一个pid。原来这个pid就是在这个地方记录下来的。查看ngx_create_pidfile函数可以看到这样的一行代码
if (ngx_process > NGX_PROCESS_MASTER) {
return NGX_OK;
},这行代码就说明了,不是master进程时,就不创建这样的一个pid文件。
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
} else {
ngx_master_process_cycle(cycle);
}
到此就基本完成Nginx的启动初始化过程了,即将开始进程相关的工作了,这里最重要的ngx_master_process_cycle这个过程,在这个过程里实现了master-worker模式的进程模型,也是生成环境下Nginx的常用模型。既然此处已不再是初始化工作,那么就留到后续分析吧。
上述所有过程都是在main函数里完成的,下一篇分析ngx_init_cycle函数。
建议继续学习:
- 配置Nginx+uwsgi更方便地部署python应用 (阅读:105405)
- 搜狐闪电邮箱的 Nginx/Postfix 使用模式 (阅读:32530)
- 解析nginx负载均衡 (阅读:14521)
- Nginx模块开发入门 (阅读:9883)
- 检查nginx配置,重载配置以及重启的方法 (阅读:9104)
- Cacti 添加 Nginx 监控 (阅读:8923)
- Nginx+FastCgi+Php 的工作机制 (阅读:8859)
- nginx的配置文件 (阅读:8834)
- 奇怪的 Nginx 的 upstream timed out 引起响应 502 (阅读:8159)
- 解决IE6从Nginx服务器下载图片不Cache的Bug (阅读:7106)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:yixiao 来源: 淘宝数据平台团队
- 标签: Nginx 初始化 启动
- 发布时间:2010-12-02 22:32:15
- [43] IOS安全–浅谈关于IOS加固的几种方法
- [43] 如何拿下简短的域名
- [42] Oracle MTS模式下 进程地址与会话信
- [42] 图书馆的世界纪录
- [41] 界面设计速成
- [39] 【社会化设计】自我(self)部分――欢迎区
- [39] android 开发入门
- [37] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 视觉调整-设计师 vs. 逻辑
- [33] Go Reflect 性能