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的定义

标签:C/C++, Linux, Nginx

评论已关闭