目录
前言
前面在介绍ngx_cycle_t结构体的初始化时,我们深入到了ngx_cycle_init函数中。在那里我们说过,对ngx_cycle_t->conf_ctx的初始化是占篇幅最大的一部分。而之前我们在介绍ngx_cycle_t结构体中的各个成员时,曾经说过,conf_ctx保存的主要是Nginx中所有模块的配置结构体,当时说模块的配置结构体主要是用于保存它感兴趣的配置项的值,而对这些模块配置结构体的初始化过程是随着对配置文件的解析一起进行的,也就是在解析配置文件的过程中不断初始化这些配置结构体。当然并不是所有的配置结构体都是由感兴趣配置项组成的,有些模块的配置结构体主要是起到组织作用,除此之外,还会保存一些重要的属性信息,当然这些信息并不是从配置文件中得到的。这些我们在这篇文章中都会进行仔细分析。
下面我们先从conf_ctx说起,然后引出Nginx的模块类型,并根据Nginx模块结构体来介绍Nginx是怎么随着配置文件的解析不断加载它的配置结构信息的,这里其实就是介绍各个模块是怎么找到它的感兴趣配置项的。当然我们会顺便介绍一下Nginx配置文件的解析过程。
关于conf_ctx
在介绍ngx_cycle_t结构体时,我们曾经简单介绍过conf_ctx组织模块配置结构体的形式。如下图所示
所有数组里面的元素都是指针类型,因为不管是什么类型的指针,所占的内存容量都是一样的,因此将数组元素设置成指针类型有利于实现多态,也就是同一个数组里面的不同元素可以指向不同的结构体。
这里需要注意的是,虽然根据图中,不同level的数组具有的含义都不一样,但事实是:图中每个数组中的每个元素指向的都是一个模块的配置结构体。这句话中还包含了另一层含义,也就是可能有些模块的配置结构体时一个数组形式。之所以说是数组形式,是因为配置结构体实质是struct类型的。比如
typedef struct {
void **main_conf;
void **srv_conf;
void **loc_conf;
} ngx_http_conf_ctx_t;
这是某个核心模块的配置结构体的形式,虽然它是struct类型,但是它的形式是数组形式。之所以struct可以表现出数组的形式,主要的原因正如我们前面所说,利用到了指针的多态性质。这个数组包含三个元素。
虽然说不管是哪个level的数组中的元素指向的都是模块的配置结构体,但是从图中我们也可以看到,这里面是有层级关系的,这种层级关系表现在配置文件中就是嵌套的语法形式。因此我们可以说模块之间是存在一定的主从关系的。我们下面将分析Nginx中模块的形式,剖析模块的这种层级主从关系。完了再回头看conf_ctx。
Nginx中的模块
所谓 模块就是C中的一个struct。下面先从Nginx模块的形式开始,然后介绍Nginx的模块类型,最后回到conf_ctx看各种类型的模块是怎么在conf_ctx中组织起来的。
Nginx模块的形式(ngx_module_s)
Nginx模块就是一个ngx_mo