首先来看涉及的一些数据结构(有的结构只列出了我们将要使用的成员):
typedef struct {
void **main_conf;
void **srv_conf;
void **loc_conf;
} ngx_http_conf_ctx_t;
typedef struct ngx_cycle_s ngx_cycle_t;
struct ngx_cycle_s {
void ****conf_ctx;
//其余成员没有列出
};
typedef struct {
ngx_array_t servers; /* ngx_http_core_srv_conf_t */
ngx_http_phase_engine_t phase_engine;
ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1];
} ngx_http_core_main_conf_t;
typedef struct {
/* array of the ngx_http_server_name_t, "server_name" directive */
ngx_array_t server_names;
/* server ctx */
ngx_http_conf_ctx_t *ctx;
ngx_str_t server_name;
} ngx_http_core_srv_conf_t;
typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
struct ngx_http_core_loc_conf_s {
ngx_str_t name; /* location name */
/* pointer to the modules' loc_conf */
void **loc_conf;
ngx_http_handler_pt handler;
ngx_queue_t *locations;
};
typedef struct {
ngx_queue_t queue;
ngx_http_core_loc_conf_t *exact;
ngx_http_core_loc_conf_t *inclusive;
ngx_str_t *name;
u_char *file_name;
ngx_uint_t line;
ngx_queue_t list;
} ngx_http_location_queue_t;
HTTP框架主要由1个核心模块(ngx_http_module)和2个http模块(ngx_http_core_module和ngx_http_upstream_module)组成,他们将负责调度其他http模块一起处理用户请求。
大致规则如下:
- ngx_cycle_t的conf_ctx指向所有核心模块的配置项,其中第7个是ngx_http_module的配置项,其结构类型为ngx_http_conf_ctx_t;
- http框架在遇到http、server和location时都会生成一个ngx_http_conf_ctx_t结构体;
- main级别的ngx_http_conf_ctx_t成员main_conf、srv_conf和loc_conf分别指向所有http模块create_main_conf,create_srv_conf和create_loc_conf生成的结构体;
- main级别下ngx_http_conf_ctx_t的main_conf指向的第一个结构体类型是ngx_http_core_main_conf_t,而ngx_http_core_main_conf_t的servers成员是一个动态数组,数组类型为ngx_http_core_srv_conf_t;而ngx_http_core_srv_conf_t的ctx指向server级别下的ngx_http_conf_ctx_t,这样就把main和server连接起来了;
- server级别下ngx_http_conf_ctx_t的loc_conf成员指向的第一个结构体类型是ngx_http_core_loc_conf_t,而ngx_http_core_loc_conf_t的loc_conf成员指向ngx_http_location_queue_t,而ngx_http_location_queue_t的queue成员会把本server下的所有location串联起来;这样又把server和location串联起来了;结合第4点,main,server和location的所有配置项都串联成一个整体了;
- ngx_http_location_queue_t的exact或者inclusive成员指向ngx_http_core_loc_conf_t,而ngx_http_core_loc_conf_t的loc_conf成员指向所有http模块由create_loc_conf方法生成的结构体,这样在location下就能获取所有http模块的配置项了。
- 配置项合并规则:
- 在server级别会调用merge_srv_conf合并main和server下用create_srv_conf创建的配置项;也会调用merge_loc_conf来合并main和serve下用create_loc_conf创建的配置项
- 在location级别会调用merge_loc_conf合并server和location下调用create_loc_conf创建的配置项。
具体的内存分布图如下(可以点击放大后查看):