Nginx源码分析核心模块加载
装载请注明出处:http://www.firefoxbug.com/?p=2053
之前一篇Nginx源码分析模块加载大概描述了Nginx官方定义的6个核心模块,本文再详细介绍这几类模块的加载。这些核心模块都属于宏NGX_CORE_MODULE,对应的模块上下文配置结构体是 ngx_core_module_t。
typedef struct { ngx_str_t name; //模块名,即ngx_core_module_ctx结构体对象的 void *(*create_conf)(ngx_cycle_t *cycle); //解析配置项,nginx框架会调用create_conf方法 char *(*init_conf)(ngx_cycle_t *cycle, void *conf); //解析配置项完成后,nginx框架会调用init_conf方法 } ngx_core_module_t;
NGX_CORE_MODULE这6类核心模块都用ngx_core_module_t接口定义上下文。
-------nginx-1.0.13/src/core/nginx.c------- 162:static ngx_core_module_t ngx_core_module_ctx = { ngx_string("core"), ngx_core_module_create_conf, ngx_core_module_init_conf }; ------nginx-1.0.13/src/event/ngx_event.c------- 93:static ngx_core_module_t ngx_events_module_ctx = { ngx_string("events"), NULL, NULL }; -------nginx-1.0.13/src/http/ngx_http.c------- 95:static ngx_core_module_t ngx_http_module_ctx = { ngx_string("http"), NULL, NULL }; -------nginx-1.0.13/src/core/ngx_log.c------- 28:static ngx_core_module_t ngx_errlog_module_ctx = { ngx_string("errlog"), NULL, NULL }; -------nginx-1.0.13/src/event/ngx_event_openssl.c------- 59:static ngx_core_module_t ngx_openssl_module_ctx = { ngx_string("openssl"), ngx_openssl_create_conf, NULL }; -------nginx-1.0.13/src/mail/ngx_mail.c------- 50:static ngx_core_module_t ngx_mail_module_ctx = { ngx_string("mail"), NULL, NULL };
前面说了每一种核心模块都可以重新定义本类型的模块,下面是几种重新定义的类型。
#define NGX_CORE_MODULE 0x45524F43 /* "CORE" */ #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ #define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */ #define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */ #define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */
定义了新的模块类型后,那么对应的模块上下文也是新的结构。比如HTTP模块类型(NGX_HTTP_MODULE)上下文是ngx_http_module_t。下面看个Nginx的配置文件
user nobody; #ngx_core_module_t-->> ngx_core_module_ctx worker_processes 1; error_log logs/error.log; #ngx_core_module_t-->>ngx_errlog_module_ctx events { #ngx_core_module_t-->>ngx_events_module_ctx #------NGX_EVENT_MODULE START----------# #NGX_EVENT_MODULE ctx -->> ngx_event_module_t worker_connections 1024; accept_mutex on; use epoll; connections 1024; worker_connections 1024; #------NGX_EVENT_MODULE END----------# } http { #--------NGX_HTTP_MODULE START---------# #NGX_HTTP_MODULE ctx -->> ngx_http_module_t log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; keepalive_timeout 65; gzip on; server { listen 80; server_name localhost; access_log logs/host.access.log main; location / { root html; index index.html index.htm; } #---------NGX_HTTP_MODULE END---------# }
Nginx模块的加载可以查看前文,总结下:
src/core/nginx.c -->> main() cycle = ngx_init_cycle(&init_cycle); #模块加载入口 | 遍历所有模块找到NGX_CORE_MODULE类型,调用module->create_conf创建模块结构体配置 | 设置第一步解析类型为NGX_CORE_MODULE(conf.module_type = NGX_CORE_MODULE;) | 开始解析配置文件(ngx_conf_parse),这里开始递归加载模块,比较复杂,见下文Nginx源码分析HTTP模块加载 | 读取完配置文件,加载完模块,遍历所有模块找到NGX_CORE_MODULE类型调用init_conf,初始化模块结构体配置 | listen socket的初始化,创建并bind等操作, 打开所有的监听套接口(ngx_open_listening_sockets) | 对所有模块进行初始化,具体为调用init_module,注意这里是所有模块。具体可以查看ngx_module_t的定义
评论已关闭