想要理解nginx服务器的源码,那么首先就必须理解它的模块化的思想,因为nginx是master加worker的方式进行运行的,因而在master进程以及worker进程中都会涉及到许多模块的初始化的地方,例如创建配置,读取配置等。在模块内又会提供许多的回调函数,这样在合适的地方调用这些回调函数就可以了。
首先来看nginx模块化的最基本结构ngx_module_t,它的定义是在Src/Core/Ngx_conf_file.h里面:
#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1
#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
//模块的数据结构定义
struct ngx_module_s {
ngx_uint_t ctx_index; //分类模计数器
ngx_uint_t index; //模块计数器
ngx_uint_t spare0;
ngx_uint_t spare1;
ngx_uint_t spare2;
ngx_uint_t spare3;
ngx_uint_t version; //版本
void *ctx; //该模块的上下文,也就是说指向的是哪一个模块,core或者event或者http或者mail,conf
ngx_command_t *commands; //该模块的命令集,指向一个ngx_command_t结构数组
ngx_uint_t type; //该模块的种类,为core/event/http/mail中的一种
ngx_int_t (*init_master)(ngx_log_t *log); //初始化master
ngx_int_t (*init_module)(ngx_cycle_t *cycle); //初始化模块
ngx_int_t (*init_process)(ngx_cycle_t *cycle); //初始化工作进程的时候调用
ngx_int_t (*init_thread)(ngx_cycle_t *cycle); //初始化线程的时候调用
void (*exit_thread)(ngx_cycle_t *cycle); //退出线程
void (*exit_process)(ngx_cycle_t *cycle); //退出进程
void (*exit_master)(ngx_cycle_t *cycle); //退出master
uintptr_t spare_hook0;
uintptr_t spare_hook1;
uintptr_t spare_hook2;
uintptr_t spare_hook3;
uintptr_t spare_hook4;
uintptr_t spare_hook5;
uintptr_t spare_hook6;
uintptr_t spare_hook7;
};
具体每一个域的作用在上面已经标示了出来,nginx会有一个全局的变量ngx_modules用来保存所有的模块,nginx模块分为五种类型,core,event,http,mail以及conf,ctx_index域就是用来保存每个模块相对于自己类型的模块其索引号是多少,这在以后创建以及获取配置是很有用的,因为nginx将配置按照模块的类型进行了分类,例如在Src/Event/Ngx_event.c中就有如下的代码进行event模块的ctx_index域的初始化:
ngx_event_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
continue;
}
ngx_modules[i]->ctx_index = ngx_event_max_module++; //记录当前事件模块的事件模块分类索引
}
其余类型的模块的ctx_index的初始化与其实类似的。
另外还有一个非常重要的域,ctx,指的是当前模块的上下文,因为有五种模块的类型,那么就会有五种类型的上下文,指向具体对应的模块。
还有一个commands命令集,nginx的模块都有自定义的一些命令,这些命令将会与配置文件中相应的配置信息对应,每一个命令在源码中都对应着一个ngx_command_t的结构,nginx会在配置文件中将命令读取出来,放到commands数组当中,ngx_command_t的定义也是在Src/Core/Ngx_conf_file.h里面:
struct ngx_command_s {
ngx_str_t name; //命令的名字
ngx_uint_t type; //命令的类型
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); //命令的回调函数
ngx_uint_t conf;
ngx_uint_t offset;
void *post;
};
在编译了源码之后,可以在生成的objs目录下面的ngx_modules.c文件内看到导出的所有模块:
00001:
00002: #include <ngx_config.h>
00003: #include <ngx_core.h>
00004:
00005:
00006:
00007: extern ngx_module_t ngx_core_module;
00008: extern ngx_module_t ngx_errlog_module;
00009: extern ngx_module_t ngx_conf_module;
00010: extern ngx_module_t ngx_events_module;
00011: extern ngx_module_t ngx_event_core_module;
00012: extern ngx_module_t ngx_epoll_module;
00013: extern ngx_module_t ngx_http_module;
00014: extern ngx_module_t ngx_http_core_module;
00015: extern ngx_module_t ngx_http_log_module;
00016: extern ngx_module_t ngx_http_upstream_module;
00017: extern ngx_module_t ngx_http_static_module;
00018: extern ngx_module_t ngx_http_autoindex_module;
00019: extern ngx_module_t ngx_http_index_module;
00020: extern ngx_module_t ngx_http_auth_basic_module;
00021: extern ngx_module_t ngx_http_access_module;
00022: extern ngx_module_t ngx_http_limit_zone_module;
00023: extern ngx_module_t ngx_http_limit_req_module;
00024: extern ngx_module_t ngx_http_geo_module;
00025: extern ngx_module_t ngx_http_map_module;
00026: extern ngx_module_t ngx_http_split_clients_module;
00027: extern ngx_module_t ngx_http_referer_module;
00028: extern ngx_module_t ngx_http_rewrite_module;
00029: extern ngx_module_t ngx_http_proxy_module;
00030: extern ngx_module_t ngx_http_fastcgi_module;
00031: extern ngx_module_t ngx_http_uwsgi_module;
00032: extern ngx_module_t ngx_http_scgi_module;
00033: extern ngx_module_t ngx_http_memcached_module;
00034: extern ngx_module_t ngx_http_empty_gif_module;
00035: extern ngx_module_t ngx_http_browser_module;
00036: extern ngx_module_t ngx_http_upstream_ip_hash_module;
00037: extern ngx_module_t ngx_http_stub_status_module;
00038: extern ngx_module_t ngx_http_write_filter_module;
00039: extern ngx_module_t ngx_http_header_filter_module;
00040: extern ngx_module_t ngx_http_chunked_filter_module;
00041: extern ngx_module_t ngx_http_range_header_filter_module;
00042: extern ngx_module_t ngx_http_gzip_filter_module;
00043: extern ngx_module_t ngx_http_postpone_filter_module;
00044: extern ngx_module_t ngx_http_ssi_filter_module;
00045: extern ngx_module_t ngx_http_charset_filter_module;
00046: extern ngx_module_t ngx_http_userid_filter_module;
00047: extern ngx_module_t ngx_http_headers_filter_module;
00048: extern ngx_module_t ngx_http_copy_filter_module;
00049: extern ngx_module_t ngx_http_range_body_filter_module;
00050: extern ngx_module_t ngx_http_not_modified_filter_module;
00051:
这些模块都是在此处用extern进行申明的,而具体的定义则在相应的.c文件当中进行的,例如ngx_epoll_module的申明是在Ngx_epoll_module.c文件中。
同样在生成的objs目录下面的ngx_modules.c文件内可以看到前面提到的全局变量ngx_modules的定义:
00052: ngx_module_t *ngx_modules[] = {
00053: &ngx_core_module,
00054: &ngx_errlog_module,
00055: &ngx_conf_module,
00056: &ngx_events_module,
00057: &ngx_event_core_module,
00058: &ngx_epoll_module,
00059: &ngx_http_module,
00060: &ngx_http_core_module,
00061: &ngx_http_log_module,
00062: &ngx_http_upstream_module,
00063: &ngx_http_static_module,
00064: &ngx_http_autoindex_module,
00065: &ngx_http_index_module,
00066: &ngx_http_auth_basic_module,
00067: &ngx_http_access_module,
00068: &ngx_http_limit_zone_module,
00069: &ngx_http_limit_req_module,
00070: &ngx_http_geo_module,
00071: &ngx_http_map_module,
00072: &ngx_http_split_clients_module,
00073: &ngx_http_referer_module,
00074: &ngx_http_rewrite_module,
00075: &ngx_http_proxy_module,
00076: &ngx_http_fastcgi_module,
00077: &ngx_http_uwsgi_module,
00078: &ngx_http_scgi_module,
00079: &ngx_http_memcached_module,
00080: &ngx_http_empty_gif_module,
00081: &ngx_http_browser_module,
00082: &ngx_http_upstream_ip_hash_module,
00083: &ngx_http_stub_status_module,
00084: &ngx_http_write_filter_module,
00085: &ngx_http_header_filter_module,
00086: &ngx_http_chunked_filter_module,
00087: &ngx_http_range_header_filter_module,
00088: &ngx_http_gzip_filter_module,
00089: &ngx_http_postpone_filter_module,
00090: &ngx_http_ssi_filter_module,
00091: &ngx_http_charset_filter_module,
00092: &ngx_http_userid_filter_module,
00093: &ngx_http_headers_filter_module,
00094: &ngx_http_copy_filter_module,
00095: &ngx_http_range_body_filter_module,
00096: &ngx_http_not_modified_filter_module,
00097: NULL
00098: };
00099:
这里来分析nginx是如何初始化这些模块的:
(1)静态初始化(编译的时候的初始化):首先是调用NGX_MODULE_V1初始化前面7个不知道干什么用的域,接着用全局对象ngx_mname_module_ctx的地址来初始化ctx域,接着用全局数组ngx_mname_commands来初始化模块的commands域,然后用宏来初始化type字段,然后初始化init_master等回调函数,最后初始化最后8个不知道干嘛用的字段。
(2)动态初始化:在main函数中,会有如下的代码来初始化每个模块的index:
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++;
}
然后对于ctx_index的初始化前面已经介绍过了。
本文的引用:
http://blog.youkuaiyun.com/livelylittlefish/article/details/6571497
http://blog.youkuaiyun.com/kenbinzhang/article/details/4663258
1570

被折叠的 条评论
为什么被折叠?



