nginx中功能模块抽象接口(Interface),所有要加入到nginx项目中的功能模块必须实现此接口,实现此接口的模块实例将会初始化到全局数组ngx_modules[]中,该数组在项目编译时生成.
typedef struct ngx_module_s ngx_module_t;接口定义 :
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; };几个重要参数说明:
index:该模块的参数配置结构信息在ngx_cycle_t中的参数配置结构指针列表conf_ctx中的索引。
ctx:实现ngx_module_t接口的具体功能模块实例对应的私有配置参数(创建及初始化)的接口指针,具体模块具体实现自己的参数创建及解析。
commands:具体功能模块配置参数,Nginx已经实现从文件读取参数的方法,最终读出来的每个参数表示什么意义及如何解析他们对应的值,由接口指针commands(类型为ngx_command_t )提供具体实现。
type: 该模块实例的类型标识,在ngx_modules[]数组中查询具体模块时会用到。
下面是Nginx中的核心模块ngx_core_module实现此接口的示例:
全局变量ngx_core_module对ngx_module_t接口的实现:
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 };
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;
static ngx_core_module_t ngx_core_module_ctx = { ngx_string("core"), ngx_core_module_create_conf, ngx_core_module_init_conf };即 ngx_core_module模块是调用上面两个接口ngx_core_module_create_conf&ngx_core_module_init_conf来获取自己的配置参数,并初始化自己的配置参数结构ngx_core_conf_t.
ngx_core_conf_t参数结构定义如下(具体对应配置文件中的值):
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; uint64_t *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; #if (NGX_THREADS) ngx_int_t worker_threads; size_t thread_stack_size; #endif } ngx_core_conf_t;
static ngx_command_t ngx_core_commands[] = { { ngx_string("daemon"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, 0, offsetof(ngx_core_conf_t, daemon), NULL }, { ngx_string("master_process"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, 0, offsetof(ngx_core_conf_t, master), NULL }, { ngx_string("timer_resolution"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, 0, offsetof(ngx_core_conf_t, timer_resolution), NULL }, { ngx_string("pid"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, pid), NULL }, { ngx_string("lock_file"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, lock_file), NULL }, { ngx_string("worker_processes"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_worker_processes, 0, 0, NULL }, { ngx_string("debug_points"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_enum_slot, 0, offsetof(ngx_core_conf_t, debug_points), &ngx_debug_points }, { ngx_string("user"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12, ngx_set_user, 0, 0, NULL }, { ngx_string("worker_priority"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_priority, 0, 0, NULL }, { ngx_string("worker_cpu_affinity"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE, ngx_set_cpu_affinity, 0, 0, NULL }, { ngx_string("worker_rlimit_nofile"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, rlimit_nofile), NULL }, { ngx_string("worker_rlimit_core"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_off_slot, 0, offsetof(ngx_core_conf_t, rlimit_core), NULL }, { ngx_string("worker_rlimit_sigpending"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, rlimit_sigpending), NULL }, { ngx_string("working_directory"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, 0, offsetof(ngx_core_conf_t, working_directory), NULL }, { ngx_string("env"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_env, 0, 0, NULL }, #if (NGX_THREADS) { ngx_string("worker_threads"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_core_conf_t, worker_threads), NULL }, { ngx_string("thread_stack_size"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, 0, offsetof(ngx_core_conf_t, thread_stack_size), NULL }, #endif ngx_null_command };即配置文件中的每个参数对应一个ngx_command_s 接口去获取其值(如上示例):
ngx_command_s结构定义如下:
struct ngx_command_s { ngx_str_t name; ngx_uint_t type; char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); ngx_uint_t conf; ngx_uint_t offset; void *post; };即为每个参数实现一个ngx_command_s接口即可,具体实现参看 ngx_core_commands里的各个参数解析接口实现.