nginx所有功能都实现模块化,包括核心功能和基础设施,例如core模块和errorlog模块,一般软件都会设计成一个核心代码和共用库,而在nginx中却是一个模块。模块的加载、卸载目前不支持运行时动态调整,需要在编译阶段通过configure自动进行,用户扩展的模块代码放到addon目录下会被自动搜索、配置。

configure生成ngx_modules.c文件,该文件定义了ngx_modules全局变量,包括了所有加载的模块定义。

ngx_module_t *ngx_modules[] = {
    &ngx_core_module,
    &ngx_errlog_module,
    &ngx_conf_module,
...
}

目前定义了5种模块类型,如果要扩充支持FTP协议,就可能需要增加模块类型了。NGX_CORE_MODULE类型为一级模块,在配置文件中,一级模块的配置指令为第一层次,例如http/event等指令。ngx_http_module是一级模块,在其下还有一系列类型为NGX_HTTP_MODULE的二级模块,如:ngx_http_core_module等,一般开发http模块的类型都是这种。

#define NGX_CORE_MODULE      0x45524F43  /* "CORE" */
#define NGX_CONF_MODULE      0x464E4F43  /* "CONF" */
#define NGX_EVENT_MODULE      0x544E5645  /* "EVNT" */
#define NGX_HTTP_MODULE           0x50545448   /* "HTTP" */
#define NGX_MAIL_MODULE         0x4C49414D     /* "MAIL" */

再来看ngx_module_t的结构定义,以core模块为例,NGX_MODULE_V1NGX_MODULE_V1_PADDING是一堆预留字段,ngx_core_module_ctxngx_core_commands与配置相关。不同类型模块的ctx和commands定义不同,例如http模块的ctx定义了server、loc等配置函数,event的ctx定义了io处理函数。下面的一堆钩子定义了模块的初始化和退出函数,用的比较少。

ngx_module_t  ngx_core_module = {
    NGX_MODULE_V1,
    &ngx_core_module_ctx,                  /* module context */
    ngx_core_commands,                     /* module directives */
    NGX_CORE_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

epoll等通讯模块的module_ctx定义了,事件处理函数,其中的ngx_epoll_process_events是worker进程主处理循环的入口。

ngx_event_module_t  ngx_epoll_module_ctx = {
    &epoll_name,
    ngx_epoll_create_conf,               /* create configuration */
    ngx_epoll_init_conf,                 /* init configuration */

    {
        ngx_epoll_add_event,             /* add an event */
        ngx_epoll_del_event,             /* delete an event */
        ngx_epoll_add_event,             /* enable an event */
        ngx_epoll_del_event,             /* disable an event */
        ngx_epoll_add_connection,        /* add an connection */
        ngx_epoll_del_connection,        /* delete an connection */
        NULL,                            /* process the changes */
        ngx_epoll_process_events,        /* process the events */
        ngx_epoll_init,                  /* init the events */
        ngx_epoll_done,                  /* done the events */
    }
};

核心模块初始化在函数ngx_init_cycle(ngx_cycle_t *old_cycle)中完成,这个函数还做了很多其他初始化工作。其中最主要的工作就是解析配置文件,根据配置指令,完成各个模块的初始化,例如监听端口等。


Simon Lee

My blog