想要理解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.csdn.net/livelylittlefish/article/details/6571497