nginx配置解析(一)
第一个问题:配置项的位置
想了解配置项应该配置在那个位置,需要先明白一个道理,nginx的配置是提供给谁使用的? 我们总说nginx是一个模块化的程序,它把程序划分成一个个的模块,自然而然的就可以联想到这些配置项正是提供给各个模块所使用,每个模块都有它所支持的专属的配置。 进而,我们可以猜测,决定配置项所属位置的主要因素是需要它的模块要把它放在什么位置!
那么nginx的模块是怎么决定它的配置项所在的位置的呢? 这就要看nginx的一个关键数据结构 ngx_command_t
了~ ngx_command_t
所代表的就是一个模块所需要的配置项,每个模块中,都会去实现一个ngx_command_t
类型的数组。至于为什么是数组?原因很简单啊,一个模块所需要的配置项一般都不止一种......
现在看一下这个ngx_command_t
长什么样子
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;};复制代码
下面分别解释一下上面结构体各个变量的意义:
字段 | 意义 |
---|---|
name | 配置项的名字,譬如worker_process 等 |
type | 决定了你参数的相关属性,譬如出现在哪里,有几个参数等 |
set | nginx从配置文件中读取到当前指定的配置项的值后,会调用该函数指针所指向的函数进行处理 |
conf | 这个和配置在内存中的组织形式有关,要根据这个标识找到配置存到内存那个位置,可以先不用理解此项的意义,后面会讲到 |
offset | 一般一个模块的配置项都会在一个结构体内,这里的offset就是存储这个配置项的变量在整个结构体中的字节偏移量(外部用它来获取配置项的值) |
post | 略(一般用不到,后面有机会再讲) |
好了,现在让我们再回顾一下我们的问题是什么:配置项所在的位置是怎么决定的?为什么有的配置项是在文件外层,有的是在某个配置块内?
对于这个问题,目前我们可以给出一个笼统的初步的答案:
每个模块为了灵活实现自己的功能,都会提供相关的配置项。这个配置项用
ngx_command_t
结构体来描述它,因为一般的一个模块所需的配置项不止一条,因此nginx规定模块必须提供一个ngx_command_t
数组。 对于单独的某一条配置项来说,想指定它们在配置文件中的位置,只需要把ngx_command_t->type
的值指定为特定的值即可。
下面,我将给出确认配置项在配置文件中位置有关的type的值:
type取值 | 意义 |
---|---|
NGX_MAIN_CONF | 配置项出现在全局配置中,不属于任何{}配置块 |
NGX_EVENT_CONF | 配置项出现在额events{}块内 |
NGX_MAIL_MAIN_CONF | 配置项出现在mail{}或者imap{}块内 |
NGX_MAIL_SRV_CONF | 配置项出现在server{}块内,然而该server{}块必须属于mail{}块或者imap{}块 |
NGX_HTTP_MAIN_CONF | 配置项出现在http{}块内 |
NGX_HTTP_SRV_CONF | 配置项出现在server{}块内,然而该server{}块必须属于http{}块 |
NGX_HTTP_LOC_CONF | 配置项出现在location{}块内,然而该location{}块必须属于http{}块 |
NGX_HTTP_UPS_CONF | 配置项出现在upstream{}块内,然而该upstream{}块必须属于http{}块 |
NGX_HTTP_SIF_CONF | 配置项出现在server{}块内的if{}块中,该if块必须属于http块,目前只有rewrite模块会使用该type |
NGX_HTTP_LIF_CONF | 配置项出现在location{}块内的if{}块中,该if块必须属于http块,目前只有rewrite模块会使用该type |
NGX_HTTP_LMT_CONF | 配置项出现在limit_except{}块内,然而该limit_except块必须属于http{} |
对于nginx在源码中对上面取值的具体处理,本章节暂时不做探讨,因为这个涉及到了nginx在内存中是怎么组织这个配置文件的,后面的章节会对其进行详细解释。 最后,我将随便具几个nginx模块的例子,看看它们所定义的ngx_command_t
数组:
ngx_core_module
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_shutdown_timeout"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, 0, offsetof(ngx_core_conf_t, shutdown_timeout), 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 }, { ngx_string("load_module"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_load_module, 0, 0, NULL }, ngx_null_command};复制代码
ngx_http_access_module
static ngx_command_t ngx_http_access_commands[] = { { ngx_string("allow"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |NGX_CONF_TAKE1, ngx_http_access_rule, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("deny"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |NGX_CONF_TAKE1, ngx_http_access_rule, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command};复制代码
配置解析系列: