Nginx的代码结构相对来说,还是非常清晰明了的,共包含有core/event/http/mail四个模块。
1. 模块结构
1. nginx包含core/event/http/mail四个核心模块。除了这四个核心模块,nginx还可以包含很多子模块,这些模块,可以在编译的时候进行选择。利用
./configure --help命令,可以查看包含的子模块,如--with-XXX-module。
用configure配置后,会生成一个objs/目录,有个ngx_modules.c文件里面声明了所包含的模块ngx_module_t *ngx_modules[]。
2. 模块的组织(以core模块为例)
模块包含以下三个重要的数据结构:(1)模块的声明
ngx_module_t ngx_core_module;(2)模块上下文
ngx_core_module_t ngx_core_module_ctx;(3)模块支持的命令
ngx_command_t ngx_core_commands[]。
ngx_module_t中有几个参数值得注意:(1)ngx_command_t* commands,该模块支持的命令;(2)ngx_uint_t type,该模块所属的类型NGX_CORE_MODULE/NGX_EVENT_MODULE/NGX_HTTP_MODULE/NGX_MAIL_MODULE等;(3)void* ctx,模块的上下文,用来存放ngx_core_module_t结构的地址。由于所有的模块的ctx,都存放在一个大的结构
ngx_cycle_t中,如何找到每个模块的ctx呢?那就是ngx_uint_t index和ngx_uint_t ctx_index共同定位。在main()函数的代码中,有这样一段:
ngx_max_module = 0;
//从0开始计数
for (i = 0; ngx_modules[i]; i++) {
//遍历各模块
ngx_modules[i]->index = ngx_max_module++;
// 给不同的模块编号
}
... ...
for (i = 0; ngx_modules[i]; i++)
{
if ( ngx_modules[i]->type != NGX_CORE_MODULE )
// 对NGX_CORE_MODULE模块计数
{
continue;
}
module = ngx_modules[i]->ctx;
//根据ctx找到NGX_CORE_MODULE的上下文结构
if ( module->create_conf )
{
rv = module->create_conf(cycle);
//调用回调函数ngx_core_module_create_conf
if ( rv == NULL )
{
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_ctx[ngx_modules[i]->index] = rv;
//加入到cycle结构中
}
}
3. core模块的上下文结构,解析配置文件,构造配置文件,初始化配置文件的时候,会调用其回调函数。
typedef struct {
ngx_str_t name;
//名字
void *(*create_conf)(ngx_cycle_t *cycle);
// 构造配置时调用
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
//初始化配置时调用
} ngx_core_module_t;
struct ngx_command_s {
ngx_str_t name;
// 指令的名字
ngx_uint_t type;
// 指令所在模块的类别
// 从配置文件中,把指令的参数@cf,转换为合适的类型,保存在 @conf中
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
ngx_uint_t conf;
// 指针的偏移,用于 @set 函数 ; 指令解析后的存放位置
ngx_uint_t offset; //
void *post;
};
2. main函数分析
-
int main(int argc, char *const *argv)
-
{
-
ngx_int_t i;
-
ngx_log_t *log;
-
ngx_cycle_t *cycle, init_cycle;
-
ngx_core_conf_t *ccf;
-
// 初始化错误信息,并放入到全局变量 ngx_sys_errlist 中
-
if (ngx_strerror_init() != NGX_OK) {
-
return 1;
-
}
-
// 获取启动参数
-
if (ngx_get_options(argc, argv) != NGX_OK) {
-
return 1;
-
}
-
// 用 "-v" 参数启动,进程测试
-
if (ngx_show_version) {
-
... ...
-
}
-
// 初始化,并更新时间数组
-
ngx_time_init();
-
// 获取本进程ID
-
ngx_pid = ngx_getpid();
-
// 初始化并打开log文件
-
log = ngx_log_init(ngx_prefix);
-
if (log == NULL) {
-
return 1;
-
}
-
-
/*
-
* init_cycle->log is required for signal handlers and
-
* ngx_process_options()
-
*/
-
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
-
init_cycle.log = log;
-
ngx_cycle = &init_cycle;
-
// 为ngx_cycle_t结构,分配1024的内存
-
init_cycle.pool = ngx_create_pool(1024, log);
-
if (init_cycle.pool == NULL) {
-
return 1;
-
}
-
// 保存启动参数到全局变量 ngx_argv, ngx_argc中
-
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
-
return 1;
-
}
-
-
if (ngx_process_options(&init_cycle) != NGX_OK) {
-
return 1;
-
}
-
// 操作系统参数 初始化
-
if (ngx_os_init(log) != NGX_OK) {
-
return 1;
-
}
-
-
/*
-
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
-
*/
-
// CRC 表
-
if (ngx_crc32_table_init() != NGX_OK) {
-
return 1;
-
}
-
-
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
-
return 1;
-
}
-
// 启动的时候,给不同的模块,编号码
-
ngx_max_module = 0;
-
for (i = 0; ngx_modules[i]; i++) {
-
ngx_modules[i]->index = ngx_max_module++; // 给不同的模块编号
-
}
-
// 初始化cycle结构
-
cycle = ngx_init_cycle(&init_cycle);
-
if (cycle == NULL) {
-
if (ngx_test_config) {
-
ngx_log_stderr(0, "configuration file %s test failed", init_cycle.conf_file.data);
-
}
-
return 1;
-
}
-
-
if (ngx_test_config) {
-
if (!ngx_quiet_mode) {
-
ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data);
-
}
-
return 0;
-
}
-
// 若是"-s XX"参数启动的,进入信号处理函数
-
if (ngx_signal) {
-
return ngx_signal_process(cycle, ngx_signal);
-
}
-
ngx_os_status(cycle->log);
-
ngx_cycle = cycle;
-
// 获取core模块的上下文,即配置信息
-
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
-
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
-
ngx_process = NGX_PROCESS_MASTER;
-
}
-
-
// 加入信号处理
-
if (ngx_init_signals(cycle->log) != NGX_OK) {
-
return 1;
-
}
-
// 后台运行
-
if (!ngx_inherited && ccf->daemon) {
-
if (ngx_daemon(cycle->log) != NGX_OK) {
-
return 1;
-
}
-
-
ngx_daemonized = 1;
-
}
-
-
if (ngx_inherited) {
-
ngx_daemonized = 1;
-
}
-
-
// 构造pid文件,里面写的是本进程的进程ID
-
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
-
return 1;
-
}
-
-
if (cycle->log->file->fd != ngx_stderr) {
-
if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
-
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_set_stderr_n " failed");
-
return 1;
-
}
-
}
-
-
if (log->file->fd != ngx_stderr) {
-
if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
-
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " built-in log failed");
-
}
-
}
-
-
cycle->log->file->fd = 1;
-
log->file->fd = 2;
-
ngx_use_stderr = 0;
-
-
if (ngx_process == NGX_PROCESS_SINGLE) {
-
ngx_single_process_cycle(cycle); // 单进程启动
-
} else {
-
ngx_master_process_cycle(cycle); // 多进程启动
-
}
-
-
return 0;
-
}
阅读(2880) | 评论(0) | 转发(0) |