nginx配置的内存布局

nginx的配置系统很灵活,不但支持模块自定义配置项,而且支持多级配置以及合并多级配置项。这样的设计使得nginx的配置在内存中的布局也是分成多级的,比较复杂。因此,这里采用一种自顶向下的方式进行逐级剖析。

这里需要先说明一下nginx指令的上下文环境以及有效上下文环境。nginx配置的上下文环境指的是指令在配置文件中的位置,比如配置文件全局,http块全局,http server块, mail块全局等。而nginx指令的有效上下文环境指的是指令在nginx配置文件中允许出现的位置。任何出现在其非有效上下文环境中的指令都会被nginx视为错误。

下面来看一段代码

struct ngx_cycle_s {
    void                  ****conf_ctx;
    ...
};
ngx_cycle_s结构体的conf_ctx字段是nginx配置项的最顶层入口,它是一个四级指针。那么,该怎么去理解这个conf_ctx呢?

下面的代码片段是从ngx_init_cycle函数中提取出来的,我们分析一下它的逻辑:

cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));//ngx_max_module是当前配置下nginx允许的最大模块数
...
for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = cycle->modules[i]->ctx;

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
}
可以看出,conf_ctx本身是一个数组,数组大小与当前配置下nginx允许的最大模块数一致。另外,这里还调用了类型为NGX_CORE_MODULE的模块ctx成员的create_conf回调函数,并且把返回值保存在模块在conf_ctx中对应的元素中。而这个create_conf回调函数是NGX_CORE_MODULE类型的模块实现配置环境创建的,也就是说,NGX_CORE_MODULE类型的模块的配置是保存在conf_ctx与其位置对应的元素中的。那么,哪些模块是NGX_CORE_MODULE呢?下表列出了到nginx-1.12.1为止的NGX_CORE_MODULE以及它们的源码文件和create_conf返回的实际类型:

ngx_core_modulenginx.cngx_core_conf_t *
ngx_events_modulengx_event.cvoid ***
ngx_openssl_modulengx_event_openssl.cngx_openssl_conf_t *
ngx_google_perftools_modulengx_google_perftools_module.cngx_google_perftools_conf_t *
ngx_http_modulengx_http.cngx_http_conf_ctx_t *
ngx_errlog_modulengx_log.cNULL
ngx_mail_modulengx_mail.cngx_mail_conf_ctx_t *
ngx_regex_modulengx_regex.cngx_regex_conf_t *
ngx_stream_modulengx_stream.cngx_stream_conf_ctx_t *
ngx_thread_pool_modulengx_thread_pool.cngx_thread_pool_conf_t *
前面说到,conf_ctx是void ****类型,那么这些NGX_CORE_MODULE类型的create_conf回调的返回值应该是void ***类型。从上面的表中可以看出,实际上只有ngx_events_module返回了void ***类型,其它的模块基本上都是各自模块定义的上下文环境指针,甚至是NULL。也就是说,conf_ctx的元素保存的实际数据是什么,是由该元素对应的模块类型决定的。

那么NGX_CORE_MODULE中的指令的有效上下文环境是什么呢?很容易可以想到,就是配置文件全局。也就是说,任何在NGX_CORE_MODULE类型的模块中定义的指令只能出现在配置文件最外层,不能出现在其它任何 位置。

到这里我们已经可以知道,出现在最外层的配置都会被直接保存在conf_ctx对应的元素指向的内存块中。下面是从conf_ctx的角度上看,各主要NGX_CORE_MODULE类型模块的内存布局图:


那么,非全局的配置会被保存在哪里呢?这与模块类型相关,不同类型的模块的配置内存布局各不相同,会在别的文章中单独分析。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值