在 nginx.c 中,首次使用下面的循环为所有的模块编号:
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++;
}
nginx 将模块数组放置在 objs/ngx_modules.c 中:
// nginx 模块数组 {{{
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,
&ngx_regex_module,
&ngx_http_module,
&ngx_http_core_module,
&ngx_http_log_module,
&ngx_http_upstream_module,
&ngx_http_static_module,
&ngx_http_gzip_static_module,
&ngx_http_autoindex_module,
&ngx_http_index_module,
&ngx_http_auth_basic_module,
&ngx_http_access_module,
&ngx_http_limit_conn_module,
&ngx_http_limit_req_module,
&ngx_http_geo_module,
&ngx_http_map_module,
&ngx_http_split_clients_module,
&ngx_http_referer_module,
&ngx_http_rewrite_module,
&ngx_http_ssl_module,
&ngx_http_proxy_module,
&ngx_http_fastcgi_module,
&ngx_http_uwsgi_module,
&ngx_http_scgi_module,
&ngx_http_memcached_module,
&ngx_http_empty_gif_module,
&ngx_http_browser_module,
&ngx_http_flv_module,
&ngx_http_upstream_hash_module,
&ngx_http_upstream_ip_hash_module,
&ngx_http_upstream_least_conn_module,
&ngx_http_upstream_keepalive_module,
&ngx_http_stub_status_module,
&ngx_http_write_filter_module,
&ngx_http_header_filter_module,
&ngx_http_chunked_filter_module,
&ngx_http_range_header_filter_module,
&ngx_http_gzip_filter_module,
&ngx_http_postpone_filter_module,
&ngx_http_ssi_filter_module,
&ngx_http_charset_filter_module,
&ngx_http_userid_filter_module,
&ngx_http_headers_filter_module,
&ngx_http_copy_filter_module,
&ngx_http_range_body_filter_module,
&ngx_http_not_modified_filter_module,
NULL
}; // }}}
足足 52 个 nginx 模块,构成了 nginx 的完整工作,让 nginx 可以服务于各种场景中
所有的模块都是 ngx_module_t 类型的,它定义了 nginx 模块的属性和模块的通用接口(回调函数):
// struct ngx_module_s
// nginx 模块结构 {{{
struct ngx_module_s {
ngx_uint_t ctx_index; // 所属分类标识
// core、http、event、mail
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;
}; // }}}
如 HTTP 模块 ngx_http_module 是如下这么定义的:
// ngx_module_t ngx_http_module
// 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
}; // }}}
其中,NGX_MODULE_V1 是一个宏:
#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1
通过这个宏,将 ngx_module_t 中的 ctx_index、index、spare0、spare1、spare2、spare3 全部初始化为 0,将 version 初始化为 1,目前 nginx 中所有模块 version 均为 1
ngx_http_module_ctx 是 HTTP 模块上下文结构:
// ngx_core_module_t ngx_http_module_ctx
// HTTP 模块上下文 {{{
static ngx_core_module_t ngx_http_module_ctx = {
ngx_string("http"),
NULL,
NULL
}; // }}}
nginx 模块上下文是一个指向一个结构体的指针,对应了四个不同的结构体,分别代表了四种不同的模块:core、mail、event、http,四个结构体分别是:
- ngx_core_module_t
- ngx_mail_module_t
- ngx_event_module_t
- ngx_http_module_t
他们定义了每一种类型的模块所必须的接口和字段
他们的定义如下:
// struct ngx_core_module_t
// nginx 内核模块 {{{
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; // }}}
// struct ngx_mail_module_t
// 邮件模块描述结构 {{{
typedef struct {
ngx_mail_protocol_t *protocol;
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);
} ngx_mail_module_t; // }}}
// struct ngx_event_module_t
// 事件模块结构体 {{{
typedef struct {
// 模块名称
ngx_str_t *name;
// 解析配置前,用于创建存储配置项参数结构体的回调函数
void *(*create_conf)(ngx_cycle_t *cycle);
// 解析配置完成后,用于综合处理某些配置项
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
// 对于事件驱动机制,每个事件需要实现的 10 个抽象方法
ngx_event_actions_t actions;
} ngx_event_module_t; // }}}
// struct ngx_http_module_t
// http 模块描述结构 {{{
typedef struct {
// 解析配置文件前调用
ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
// 解析配置文件后调用
ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
// 用于创建直属于 http{...} 的配置项的结构体
void *(*create_main_conf)(ngx_conf_t *cf);
// 用于初始化 main 级别配置项
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
// 用于创建只属于 server{...} 的配置项的结构体
void *(*create_srv_conf)(ngx_conf_t *cf);
// 用于合并 main 级别和 srv 级别下的同名配置项
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
// 用于创建直属于 location{...} 的配置项的结构体
void *(*create_loc_conf)(ngx_conf_t *cf);
// 用于合并 srv 级别和 loc 级别下的同名配置项
char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t; // }}}