nginx模块初始化

nginx模块初始化

1. nginx模块介绍

       在nginx编译之后,在源代码目录中会出现objs文件夹,里面有ngx_auto_config.h,ngx_auto_headers.h以及ngx_modules.c文件等。

       其中,生成的ngx_modules.c文件中,重新集中申明(使用extern关键字)nginx配置的所有模块,这些模块可通过编译前的configure命令进行配置,即设置哪些模块需要编译,哪些不被编译。如下。       
#include <ngx_config.h>
#include <ngx_core.h>
extern ngx_module_t  ngx_core_module;
extern ngx_module_t  ngx_errlog_module;
extern ngx_module_t  ngx_conf_module;
extern ngx_module_t  ngx_events_module;
extern ngx_module_t  ngx_event_core_module;
extern ngx_module_t  ngx_epoll_module;
extern ngx_module_t  ngx_openssl_module;
......
ngx_module_t *ngx_modules[] = {
    &ngx_core_module,            //模块列表
    &ngx_errlog_module,
    &ngx_conf_module,
    &ngx_events_module,
    &ngx_event_core_module,
    &ngx_epoll_module,
&ngx_openssl_module,
。。。 。。。
NULL
};

    很显然,这些模块均是在此处用extern进行申明,以表明其他模块可以访问,而对其本身的定义和初始化ngx_module_t结构在其对应的.c文件中进行。例如,ngx_core_module模块便是在./src/core/nginx.c文件中定义并进行静态初始化。实际上,ngx_core_module是一个全局的结构体对象,其他模块类同。如下。

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
};

2. 模块数据结构

    nginx的模块化架构最基本的数据结构为ngx_module_t,因此,此处,我们先分析这个结构,在./src/core/ngx_conf_file.h文件中定义。
struct ngx_module_s {
    ngx_uint_t            ctx_index; //当前模块在某一类模块中的索引
    ngx_uint_t            index; //当前模块在ngx_modules数组中的序号

    ngx_uint_t            spare0;
    ngx_uint_t            spare1;
    ngx_uint_t            spare2;
    ngx_uint_t            spare3;

    ngx_uint_t            version; //版本

    void                 *ctx; //该模块的上下文,每个种类的模块有不同的上下文
    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;
};
模块的命令集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;
};

3. 模块初始化

(1)静态初始化

即编译期间完成的数据成员初始化。记mname为某个模块的名字,其静态初始化过程如下。

(1) 用宏NGX_MODULE_V1初始化前7个字段

(2) 用全局对象ngx_mname_module_ctx的地址初始化ctx指针

(3) 用全局数组ngx_mname_commands[]初始化commands指针

(4) 用宏NGX_CORE_MODULE等初始化type字段

(5) 初始化init_mastercallback

(6) 用宏NGX_MODULE_V1_PADDING初始化最后8个字段

 

由此可见,在定义该模块(全局结构对象)时,将其ctx_indexindex均初始化为0。因此,模块的静态初始化(数据成员初始化)实际上只是对模块上下文、模块命令集和模块类型进行初始化。

(2)动态初始化
nginx运行(启动)初期,对模块本身的初始化。
下面进行index字段的初始化:
对各个模块的index字段的初始化是在main函数中进行的,如下。
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {  
   ngx_modules[i]->index = ngx_max_module++;  
  }
下面进行ctx_index字段的初始化(例如event模块的ctx_index的初始化):
static char *
ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char                 *rv;
    void               ***ctx;
    ngx_uint_t            i;
    ngx_conf_t            pcf;
    ngx_event_module_t   *m;

    /* count the number of the event modules and set up their indices */

    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++;
    }
 ........
}

参考文献:
2. 《深入理解Nginx模块开发与架构解析》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值