读书人

nginx源码翻阅笔记

发布时间: 2012-06-26 10:04:13 作者: rapoo

nginx源码阅读笔记

?

最近做一个收集客户端数据的项目, 后台使用nginx, 通过实现nginx的模块来处理业务. ?nginx的模块编写不难,

但写完后对nginx的内部机制还是云里雾里, 趁周末好好阅读一下nginx的源代码. ?下面记录一些阅读过程中遇

到的数据结构. 关于nginx的内部实现, 等看懂了源码再写.


模块四要素:

1 模块实例, 2 模块上下文, 3 模块指令, 4 指令参数


模块定义

===================================================

struct ngx_module_s {

? ? ngx_uint_t ? ? ? ? ? ?ctx_index;

? ? ngx_uint_t ? ? ? ? ? ?index;


? ? 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_uint_t ? ? ? ? ? ?type;


? ? ngx_int_t ? ? ? ? ? (*init_master)(ngx_log_t *log);


? ? 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);


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

}; ?(core/ngx_conf_file.h)


模块实例定义

===================================================

1 核心模块

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

}; (core/nginx.c)


2 http模块

ngx_module_t ?ngx_http_module = {

? ? NGX_MODULE_V1,

? ? &ngx_http_module_ctx, ? ? ? ? ? ? ? ? ?/* module context */

? ? ngx_http_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

};


3 http核心模块

ngx_module_t ?ngx_http_core_module = {

? ? NGX_MODULE_V1,

? ? &ngx_http_core_module_ctx, ? ? ? ? ? ? /* module context */

? ? ngx_http_core_commands, ? ? ? ? ? ? ? ?/* module directives */

? ? NGX_HTTP_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

}; (http/ngx_http_core_module.c)


4 日志模块

ngx_module_t ?ngx_errlog_module = {

? ? NGX_MODULE_V1,

? ? &ngx_errlog_module_ctx, ? ? ? ? ? ? ? ?/* module context */

? ? ngx_errlog_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

};


5 事件模块

ngx_module_t ?ngx_event_core_module = {

? ? NGX_MODULE_V1,

? ? &ngx_event_core_module_ctx, ? ? ? ? ? ?/* module context */

? ? ngx_event_core_commands, ? ? ? ? ? ? ? /* module directives */

? ? NGX_EVENT_MODULE, ? ? ? ? ? ? ? ? ? ? ?/* module type */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* init master */

? ? ngx_event_module_init, ? ? ? ? ? ? ? ? /* init module */

? ? ngx_event_process_init, ? ? ? ? ? ? ? ?/* init process */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* init thread */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* exit thread */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* exit process */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* exit master */

? ? NGX_MODULE_V1_PADDING

};


模块上下文定义?

===================================================

1 核心模块上下文定义

typedef struct {

? ? ngx_str_t ? ? ? ? ? ? name;

? ? void ? ? ? ? ? ? ? *(*create_conf)(ngx_cycle_t *cycle);

? ? char ? ? ? ? ? ? ? *(*init_conf)(ngx_cycle_t *cycle, void *conf);

} ngx_core_module_t; ? ? (见src/core/ngx_conf_file.h)


2 事件模块上下文定义

typedef struct {

? ? ngx_str_t ? ? ? ? ? ? ?*name;


? ? void ? ? ? ? ? ? ? ? *(*create_conf)(ngx_cycle_t *cycle);

? ? char ? ? ? ? ? ? ? ? *(*init_conf)(ngx_cycle_t *cycle, void *conf);


? ? ngx_event_actions_t ? ? actions;

} ngx_event_module_t;(见src/event/ngx_event.h)


3 http模块上下文定义

typedef struct {

? ? ngx_int_t ? (*preconfiguration)(ngx_conf_t *cf);

? ? ngx_int_t ? (*postconfiguration)(ngx_conf_t *cf);


? ? void ? ? ? *(*create_main_conf)(ngx_conf_t *cf);

? ? char ? ? ? *(*init_main_conf)(ngx_conf_t *cf, void *conf);


? ? void ? ? ? *(*create_srv_conf)(ngx_conf_t *cf);

? ? char ? ? ? *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);


? ? void ? ? ? *(*create_loc_conf)(ngx_conf_t *cf);

? ? char ? ? ? *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);

} ngx_http_module_t; ?(见src/http/ngx_http_config.h)


4 事件模块上下文定义

ngx_event_module_t ?ngx_event_core_module_ctx = {

? ? &event_core_name,

? ? ngx_event_create_conf, ? ? ? ? ? ? ? ? /* create configuration */

? ? ngx_event_init_conf, ? ? ? ? ? ? ? ? ? /* init configuration */


? ? { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }

};


模块上下文实例

===============================================================

1 核心模块上下文

static ngx_core_module_t ?ngx_core_module_ctx = {

? ? ngx_string("core"),

? ? ngx_core_module_create_conf,

? ? ngx_core_module_init_conf

}; (core/nginx.c)


2 http核心模块上下文

static ngx_http_module_t ?ngx_http_core_module_ctx = {

? ? ngx_http_core_preconfiguration, ? ? ? ?/* preconfiguration */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* postconfiguration */


? ? ngx_http_core_create_main_conf, ? ? ? ?/* create main configuration */

? ? ngx_http_core_init_main_conf, ? ? ? ? ?/* init main configuration */


? ? ngx_http_core_create_srv_conf, ? ? ? ? /* create server configuration */

? ? ngx_http_core_merge_srv_conf, ? ? ? ? ?/* merge server configuration */


? ? ngx_http_core_create_loc_conf, ? ? ? ? /* create location configuration */

? ? ngx_http_core_merge_loc_conf ? ? ? ? ? /* merge location configuration */

}; (http/ngx_http_core_module.c)



存储指令参数的结构体

===============================================================

根指令的参数

typedef struct {

? ? ?ngx_flag_t ? ? ? ? ? ? ? daemon;

? ? ?ngx_flag_t ? ? ? ? ? ? ? master;


? ? ?ngx_msec_t ? ? ? ? ? ? ? timer_resolution;


? ? ?ngx_int_t ? ? ? ? ? ? ? ?worker_processes;

? ? ?ngx_int_t ? ? ? ? ? ? ? ?debug_points;


? ? ?ngx_int_t ? ? ? ? ? ? ? ?rlimit_nofile;

? ? ?ngx_int_t ? ? ? ? ? ? ? ?rlimit_sigpending;

? ? ?off_t ? ? ? ? ? ? ? ? ? ?rlimit_core;


? ? ?int ? ? ? ? ? ? ? ? ? ? ?priority;


? ? ?ngx_uint_t ? ? ? ? ? ? ? cpu_affinity_n;

? ? ?u_long ? ? ? ? ? ? ? ? ?*cpu_affinity;


? ? ?char ? ? ? ? ? ? ? ? ? ?*username;

? ? ?ngx_uid_t ? ? ? ? ? ? ? ?user;

? ? ?ngx_gid_t ? ? ? ? ? ? ? ?group;


? ? ?ngx_str_t ? ? ? ? ? ? ? ?working_directory;

? ? ?ngx_str_t ? ? ? ? ? ? ? ?lock_file;


? ? ?ngx_str_t ? ? ? ? ? ? ? ?pid;

? ? ?ngx_str_t ? ? ? ? ? ? ? ?oldpid;


? ? ?ngx_array_t ? ? ? ? ? ? ?env;

? ? ?char ? ? ? ? ? ? ? ? ? **environment;

} ngx_core_conf_t;


http指令的参数

typedef struct {

/* 保存所有server的配置信息 */

? ? ngx_array_t ? ? ? ? ? ? ? ?servers; ? ? ? ? /* ngx_http_core_srv_conf_t */


? ? ngx_http_phase_engine_t ? ?phase_engine;


? ? ngx_hash_t ? ? ? ? ? ? ? ? headers_in_hash;


? ? ngx_hash_t ? ? ? ? ? ? ? ? variables_hash;


? ? ngx_array_t ? ? ? ? ? ? ? ?variables; ? ? ? /* ngx_http_variable_t */

? ? ngx_uint_t ? ? ? ? ? ? ? ? ncaptures;


? ? ngx_uint_t ? ? ? ? ? ? ? ? server_names_hash_max_size;

? ? ngx_uint_t ? ? ? ? ? ? ? ? server_names_hash_bucket_size;


? ? ngx_uint_t ? ? ? ? ? ? ? ? variables_hash_max_size;

? ? ngx_uint_t ? ? ? ? ? ? ? ? variables_hash_bucket_size;


? ? ngx_hash_keys_arrays_t ? ?*variables_keys;


? ? ngx_array_t ? ? ? ? ? ? ? *ports;


? ? ngx_uint_t ? ? ? ? ? ? ? ? try_files; ? ? ? /* unsigned ?try_files:1 */


? ? ngx_http_phase_t ? ? ? ? ? phases[NGX_HTTP_LOG_PHASE + 1];

} ngx_http_core_main_conf_t;



server指令的参数

typedef struct {

? ? /* array of the ngx_http_server_name_t, "server_name" directive */

? ? ngx_array_t ? ? ? ? ? ? ? ? server_names;


? ? /* server ctx,初始化http请求ngx_http_init_request时用得到 */

? ? ngx_http_conf_ctx_t ? ? ? ?*ctx;


? ? ngx_str_t ? ? ? ? ? ? ? ? ? server_name;


? ? size_t ? ? ? ? ? ? ? ? ? ? ?connection_pool_size;

? ? size_t ? ? ? ? ? ? ? ? ? ? ?request_pool_size;

? ? size_t ? ? ? ? ? ? ? ? ? ? ?client_header_buffer_size;


? ? ngx_bufs_t ? ? ? ? ? ? ? ? ?large_client_header_buffers;


? ? ngx_msec_t ? ? ? ? ? ? ? ? ?client_header_timeout;


? ? ngx_flag_t ? ? ? ? ? ? ? ? ?ignore_invalid_headers;

? ? ngx_flag_t ? ? ? ? ? ? ? ? ?merge_slashes;

? ? ngx_flag_t ? ? ? ? ? ? ? ? ?underscores_in_headers;


? ? unsigned ? ? ? ? ? ? ? ? ? ?listen:1;


? ? ngx_http_core_loc_conf_t ?**named_locations;

} ngx_http_core_srv_conf_t;


location指令的参数

struct ngx_http_core_loc_conf_s {

? ? ngx_str_t ? ? name; ? ? ? ? ?/* location name */


? ? unsigned ? ? ?noname:1; ? /* "if () {}" block or limit_except */

? ? unsigned ? ? ?lmt_excpt:1;

? ? unsigned ? ? ?named:1;


? ? unsigned ? ? ?exact_match:1;

? ? unsigned ? ? ?noregex:1;


? ? unsigned ? ? ?auto_redirect:1;


? ? /* pointer to the modules' loc_conf */

? ? void ? ? ? ?**loc_conf;


? ? uint32_t ? ? ?limit_except;

? ? void ? ? ? ?**limit_except_loc_conf;


? ? ngx_http_handler_pt ?handler;


? ? /* location name length for inclusive location with inherited alias */

? ? size_t ? ? ? ?alias;

? ? ngx_str_t ? ? root; ? ? ? ? ? ? ? ? ? ?/* root, alias */

? ? ngx_str_t ? ? post_action;


? ? ngx_array_t ?*root_lengths;

? ? ngx_array_t ?*root_values;


? ? ngx_array_t ?*types;

? ? ngx_hash_t ? ?types_hash;

? ? ngx_str_t ? ? default_type;


? ? off_t ? ? ? ? client_max_body_size; ? ?/* client_max_body_size */

? ? off_t ? ? ? ? directio; ? ? ? ? ? ? ? ?/* directio */

? ? off_t ? ? ? ? directio_alignment; ? ? ?/* directio_alignment */


? ? size_t ? ? ? ?client_body_buffer_size; /* client_body_buffer_size */

? ? size_t ? ? ? ?send_lowat; ? ? ? ? ? ? ?/* send_lowat */

? ? size_t ? ? ? ?postpone_output; ? ? ? ? /* postpone_output */

? ? size_t ? ? ? ?limit_rate; ? ? ? ? ? ? ?/* limit_rate */

? ? size_t ? ? ? ?limit_rate_after; ? ? ? ?/* limit_rate_after */

? ? size_t ? ? ? ?sendfile_max_chunk; ? ? ?/* sendfile_max_chunk */

? ? size_t ? ? ? ?read_ahead; ? ? ? ? ? ? ?/* read_ahead */


? ? ngx_msec_t ? ?client_body_timeout; ? ? /* client_body_timeout */

? ? ngx_msec_t ? ?send_timeout; ? ? ? ? ? ?/* send_timeout */

? ? ngx_msec_t ? ?keepalive_timeout; ? ? ? /* keepalive_timeout */

? ? ngx_msec_t ? ?lingering_time; ? ? ? ? ?/* lingering_time */

? ? ngx_msec_t ? ?lingering_timeout; ? ? ? /* lingering_timeout */

? ? ngx_msec_t ? ?resolver_timeout; ? ? ? ?/* resolver_timeout */


? ? ngx_resolver_t ?*resolver; ? ? ? ? ? ? /* resolver */


? ? time_t ? ? ? ?keepalive_header; ? ? ? ?/* keepalive_timeout */

};


指令定义

===========================================================

struct ngx_command_s {

? ? ngx_str_t ? ? ? ? ? ? name;

? ? ngx_uint_t ? ? ? ? ? ?type;初始化http请求: ngx_http_init_request ? ?

? ? char ? ? ? ? ? ? ? *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

? ? ngx_uint_t ? ? ? ? ? ?conf;

? ? ngx_uint_t ? ? ? ? ? ?offset;

? ? void ? ? ? ? ? ? ? ? *post;

};


cycle定义

===========================================================

struct ngx_cycle_s {

? ? void ? ? ? ? ? ? ? ? ?****conf_ctx;

? ? ngx_pool_t ? ? ? ? ? ? ? *pool;


? ? ngx_log_t ? ? ? ? ? ? ? ?*log;

? ? ngx_log_t ? ? ? ? ? ? ? ? new_log;


? ? ngx_connection_t ? ? ? ?**files;

? ? ngx_connection_t ? ? ? ? *free_connections;

? ? ngx_uint_t ? ? ? ? ? ? ? ?free_connection_n;


? ? ngx_queue_t ? ? ? ? ? ? ? reusable_connections_queue;


? ? ngx_array_t ? ? ? ? ? ? ? listening;

? ? ngx_array_t ? ? ? ? ? ? ? pathes;

? ? ngx_list_t ? ? ? ? ? ? ? ?open_files;

? ? ngx_list_t ? ? ? ? ? ? ? ?shared_memory;


? ? ngx_uint_t ? ? ? ? ? ? ? ?connection_n;

? ? ngx_uint_t ? ? ? ? ? ? ? ?files_n;


? ? ngx_connection_t ? ? ? ? *connections;

? ? ngx_event_t ? ? ? ? ? ? ?*read_events;

? ? ngx_event_t ? ? ? ? ? ? ?*write_events;


? ? ngx_cycle_t ? ? ? ? ? ? ?*old_cycle;


? ? ngx_str_t ? ? ? ? ? ? ? ? conf_file;

? ? ngx_str_t ? ? ? ? ? ? ? ? conf_param;

? ? ngx_str_t ? ? ? ? ? ? ? ? conf_prefix;

? ? ngx_str_t ? ? ? ? ? ? ? ? prefix;

? ? ngx_str_t ? ? ? ? ? ? ? ? lock_file;

? ? ngx_str_t ? ? ? ? ? ? ? ? hostname;

};


http三大配置

===========================================================

typedef struct {

? ? void ? ? ? ?**main_conf;

? ? void ? ? ? ?**srv_conf;

? ? void ? ? ? ?**loc_conf;

} ngx_http_conf_ctx_t;


解析配置文件的时候, 用结构体ngx_conf_s来暂时存放指令的参数

===========================================================

struct ngx_conf_s {

? ? char ? ? ? ? ? ? ? ? *name;

? ? ngx_array_t ? ? ? ? ?*args;


? ? ngx_cycle_t ? ? ? ? ?*cycle;

? ? ngx_pool_t ? ? ? ? ? *pool;

? ? ngx_pool_t ? ? ? ? ? *temp_pool;

? ? ngx_conf_file_t ? ? ?*conf_file;

? ? ngx_log_t ? ? ? ? ? ?*log;


? ? void ? ? ? ? ? ? ? ? *ctx;

? ? ngx_uint_t ? ? ? ? ? ?module_type;

? ? ngx_uint_t ? ? ? ? ? ?cmd_type;


? ? ngx_conf_handler_pt ? handler;

? ? char ? ? ? ? ? ? ? ? *handler_conf;

};

在ngx_init_cycle中声明一个这样的变量

ngx_conf_t conf;

然后开始解析配置文件, 这个结构体可以反复使用, 每次遇到一个指令, 就会改变conf的内容


阅读痕迹

=====================================================================

* ngx_init_cycle:

? ? * ngx_conf_t.ctx = cycle->conf_ctx;


解析配置文件

* 从ngx_init_cycle调用ngx_conf_param开始解析配置文件

* ngx_conf_param再调用ngx_conf_parse解析配置文件

* ngx_conf_parse:

? ? * 打开配置文件

? ? * for循环:

? ? ? ? * 读取文件, ngx_conf_read_token, 把指令名和参数存到ngx_conf_t结构体,

? ? ? ? ? 每次都一条指令便返回

? ? ? ? * 调用ngx_conf_handler来处理这条指令:

? ? ? ? ? ? * 寻找指令所在的模块

? ? ? ? ? ? * 检验指令在配置文件中的位置是否正确

? ? ? ? ? ? * 检验指令的参数个数是否合法

? ? ? ? ? ? * 取得指令参数要存储的地方(比如ngx_core_conf_t,用conf指针指向),这个结构体由

? ? ? ? ? ? ? 模块的create_conf来创建, 然后把它安插在 ngx_conf_t.ctx 中

? ? ? ? ? ? * 调用指令的 set 函数, 把ngx_conf_t中的参数值转存到conf指向的结构体


解析http block

如果ngx_conf_read_token返回"http {", 则调用ngx_http_block解析http block下面的配置

* ngx_http_block:

? ? * 创建ngx_http_conf_ctx_t结构体, 这时conf指针不再指向ngx_core_conf_t,?

? ? ? 而是指向ngx_http_conf_ctx_t

? ? * 数一下有多少个http模块, 并设置每个模块的index

? ? * 调用所有http模块的create_main_conf钩子,把返回的结构体安插在ngx_http_conf_ctx_t.main_conf表中

? ? ? 调用所有http模块的create_srv_conf钩子,把返回的结构体安插在ngx_http_conf_ctx_t.srv_conf表中

? ? ? 调用所有http模块的create_loc_conf钩子,把返回的结构体安插在ngx_http_conf_ctx_t.loc_conf表中

? ? * ngx_conf_t.ctx不再指向cycle->conf_ctx, 而是指向ngx_http_conf_ctx_t?

? ? * 调用所有http模块的preconfiguration钩子

? ? * 再次调用ngx_conf_parse来解析http block里面的指令, 至此http block,?

? ? ? server block, location block都解析完毕

? ? * 调用所有http模块的init_main_conf钩子?

? ? * 待续...


解析server block

解析htto block的时候, 如果遇到"server {", 则调用

server command的set方法:ngx_http_core_server, 开始解析server block

ngx_http_core_server:

? ? * 再创建一个ngx_http_conf_ctx_t结构体, 这时ngx_conf_t.ctx不再指向

? ? ? http block的ngx_http_conf_ctx_t, 而是指向这个新的ngx_http_conf_ctx_t

? ? ? ctx = new ngx_http_conf_ctx_t

? ? ? http_ctx = cf->ctx

? ? ? cf->ctx = ctx

? ? * server ctx的main_conf从http ctx继承过来

? ? ? ctx->main_conf = http_ctx->main_conf;

? ? * 调用所有http模块的create_srv_conf钩子,把返回的结构体安插在ctx.srv_conf表中

? ? ? 调用所有http模块的create_loc_conf钩子,把返回的结构体安插在ctx.loc_conf表中

? ??



http block下面三大conf的偏移量

-----------------------

#define NGX_HTTP_MAIN_CONF_OFFSET ?offsetof(ngx_http_conf_ctx_t, main_conf)

#define NGX_HTTP_SRV_CONF_OFFSET ? offsetof(ngx_http_conf_ctx_t, srv_conf)

#define NGX_HTTP_LOC_CONF_OFFSET ? offsetof(ngx_http_conf_ctx_t, loc_conf)



根据ngx_http_request_t得到三大conf

-----------------------

#define ngx_http_get_module_main_conf(r, module) ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

? ? (r)->main_conf[module.ctx_index]

#define ngx_http_get_module_srv_conf(r, module) ?(r)->srv_conf[module.ctx_index]

#define ngx_http_get_module_loc_conf(r, module) ?(r)->loc_conf[module.ctx_index]



根据ngx_conf_t得到三大conf

-----------------------

#define ngx_http_conf_get_module_main_conf(cf, module) ? ? ? ? ? ? ? ? ? ? ? ?\

? ? ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]

#define ngx_http_conf_get_module_srv_conf(cf, module) ? ? ? ? ? ? ? ? ? ? ? ? \

? ? ((ngx_http_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]

#define ngx_http_conf_get_module_loc_conf(cf, module) ? ? ? ? ? ? ? ? ? ? ? ? \

? ? ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index]



根据cycyle的conf_ctx得到main conf

-----------------------

#define ngx_http_cycle_get_module_main_conf(cycle, module) ? ? ? ? ? ? ? ? ? ?\

? ? (cycle->conf_ctx[ngx_http_module.index] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

? ? ? ? ((ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]) ? ? ?\

? ? ? ? ? ? ->main_conf[module.ctx_index]: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\

? ? ? ? NULL)



==================== ngx_http_log_module实例 ==================


ngx_http_log_create_main_conf返回的结构体

-----------------------

typedef struct {

? ? ngx_array_t ? ? ? ? ? ? ? ? formats; ? ?/* array of ngx_http_log_fmt_t */

? ? ngx_uint_t ? ? ? ? ? ? ? ? ?combined_used; /* unsigned ?combined_used:1 */

} ngx_http_log_main_conf_t;


ngx_http_log_create_loc_conf返回的结构体

-----------------------

typedef struct {

? ? ngx_array_t ? ? ? ? ? ? ? ?*logs; ? ? ? /* array of ngx_http_log_t */


? ? ngx_open_file_cache_t ? ? ?*open_file_cache;

? ? time_t ? ? ? ? ? ? ? ? ? ? ?open_file_cache_valid;

? ? ngx_uint_t ? ? ? ? ? ? ? ? ?open_file_cache_min_uses;


? ? ngx_uint_t ? ? ? ? ? ? ? ? ?off; ? ? ? ?/* unsigned ?off:1 */

} ngx_http_log_loc_conf_t;


指令

-----------------------

static ngx_command_t ?ngx_http_log_commands[] = {


? ? { ngx_string("log_format"),

? ? ? NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,

? ? ? ngx_http_log_set_format,

? ? ? NGX_HTTP_MAIN_CONF_OFFSET,

? ? ? 0,

? ? ? NULL },


? ? { ngx_string("access_log"),

? ? ? NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF

? ? ? ? ? ? ? ? ? ? ? ? |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,

? ? ? ngx_http_log_set_log, ? ?

? ? ? NGX_HTTP_LOC_CONF_OFFSET,

? ? ? 0, ?/* 如果使用自定义的set方法, 而且无须知道参数在结构体中的offset,那么offset就可以设为0 */

? ? ? NULL },


? ? { ngx_string("open_log_file_cache"),

? ? ? NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,

? ? ? ngx_http_log_open_file_cache,

? ? ? NGX_HTTP_LOC_CONF_OFFSET,

? ? ? 0,

? ? ? NULL },


? ? ? ngx_null_command

};


上下文

-----------------------

static ngx_http_module_t ?ngx_http_log_module_ctx = {

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* preconfiguration */

? ? ngx_http_log_init, ? ? ? ? ? ? ? ? ? ? /* postconfiguration */


? ? ngx_http_log_create_main_conf, ? ? ? ? /* create main configuration */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* init main configuration */


? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* create server configuration */

? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* merge server configuration */


? ? ngx_http_log_create_loc_conf, ? ? ? ? ?/* create location configration */

? ? ngx_http_log_merge_loc_conf ? ? ? ? ? ?/* merge location configration */

};


模块实例

-----------------------

ngx_module_t ?ngx_http_log_module = {

? ? NGX_MODULE_V1,

? ? &ngx_http_log_module_ctx, ? ? ? ? ? ? ?/* module context */

? ? ngx_http_log_commands, ? ? ? ? ? ? ? ? /* module directives */

? ? NGX_HTTP_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

};


==================== end of ngx_http_log_module实例 ==================



注意ngx_request_s保存有http block里面的三大conf

--------------------------------

struct ngx_http_request_s {

? ? uint32_t ? ? ? ? ? ? ? ? ? ? ? ? ?signature; ? ? ? ? /* "HTTP" */


? ? ngx_connection_t ? ? ? ? ? ? ? ? *connection;


? ? void ? ? ? ? ? ? ? ? ? ? ? ? ? ?**ctx;

? ? void ? ? ? ? ? ? ? ? ? ? ? ? ? ?**main_conf;

? ? void ? ? ? ? ? ? ? ? ? ? ? ? ? ?**srv_conf;

? ? void ? ? ? ? ? ? ? ? ? ? ? ? ? ?**loc_conf;

}



总共创建多少个ngx_http_conf_ctx_t结构体

----------------------------------------------------

http block下创建ngx_http_conf_ctx_t

在server block下创建ngx_http_conf_ctx_t

在location block下创建ngx_http_conf_ctx_t

在location block下创建ngx_http_conf_ctx_t

在location block下创建ngx_http_conf_ctx_t

结论: http block只创建一个, 每个server都会创建一个结构体, 每个location都会创建一个结构体

疑问:server block创建的ngx_http_conf_ctx_t会保存在ngx_http_core_srv_conf_t中

? ? 那么location block创建的ngx_http_conf_ctx_t保存在哪里呢?



调用 ngx_conf_parse 的时候会先保存ngx_conf_t

------------------------------------------------

ngx_conf_t save;

? ? save = *cf;

? ? cf->ctx = ctx;

? ? cf->cmd_type = NGX_HTTP_LOC_CONF;


? ? rv = ngx_conf_parse(cf, NULL);

? ??

? ? *cf = save; ?


初始化http请求: ngx_http_init_request ? ?

----------------------------------------------- ? ?

? ? ngx_http_core_srv_conf_t *cscf = addr_conf->default_server;


? ? r->main_conf = cscf->ctx->main_conf;

? ? r->srv_conf = cscf->ctx->srv_conf;

? ? r->loc_conf = cscf->ctx->loc_conf;

?

自动收割子进程

----------------------------------------------- ? ?

在master process中, 函数 ngx_signal_handler 用来处理信号, 若

接收到 SIGCHLD 信号, 表示有一个子进程退出了, 然后把变量 ngx_reap 置为 1

然后在?ngx_master_process_cycle 函数中, 若检查到 ngx_reap 等于 1,则创建

一个子进程:

if (ngx_reap) {                ngx_reap = 0;                   ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");                live = ngx_reap_children(cycle);        }
?

读书人网 >开源软件

热点推荐