我们已经了解了 nginx 的基本命令和架构原理,下面该到最让人头疼也是最不容易理解的部分了,那就是 nginx.conf 这个配置文件,下面从 nginx 的指令开始,一步步来讲解 nginx 的配置。
先来看一个典型的 nginx 配置文件示例。
main http { upstream { … } split_clients {…} map {…} geo {…} server { if () {…} location { limit_except {…} } location { location { } } } server { } }
从上面可以看到,这个配置文件中包含了多个指令块,有些指令块还是重复的,那么这在 nginx 中是一个什么样的规则?接下来会慢慢介绍。
在 nginx 配置文件中,指令块是可以互相嵌套的,例如上面的示例,http 块中可以包含多个 server 块,server 块中还会包含多个 location 块,每一个块中都有相应的指令。
而每一个指令都有 context 上下文,也就是生效的环境,这在 nginx 的官方文档中说的很清楚,例如下面的两条指令,context 中都表明了各自可以生效的环境,access_log 指令可以在多个上下文中生效:
syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; access_log off; default: access_log logs/access.log combined; context: http, server, location, if in location, limit_except syntax: log_format name [escape=default|json|none] string ...; default: log_format combined "..."; context: http
在 nginx 中,指令分为两种,一种是值指令,一种是动作类指令:
这里面的示例以及生效阶段,后面都还会详细讲,这里可以不用过多关注,既然指令分为两种,那么就有不同的继承规则,下面就来说一下。
例如下面的配置文件,这里面在 server 块和 location 块中都配置了 root 指令,nginx 的继承规则如下:
server { listen 8080; root /home/geek/nginx/html; access_log logs/geek.access.log main; location /test { root /home/geek/nginx/test; access_log logs/access.test.log main; } location /dlib { alias dlib/; } location / { }
根据上面这两条规则,第一个 location 使用自家的 root 指令,后面两个 location 则使用 server 块的 root 指令。这和编程语言中变量的作用域也是类似的,作用域更小的变量优先级往往更高,nginx 的指令也是一样。
对于很多第三方模块,很可能文档并不完善,这时候需要通过源码来查看指令的生效范围。需要明确下面几个问题:
这两个问题是在源码中定义的,例如:
static ngx_command_t ngx_http_core_commands[] = { { ngx_string("variables_hash_max_size"), ngx_http_main_conf|ngx_conf_take1, ngx_conf_set_num_slot, ngx_http_main_conf_offset, offsetof(ngx_http_core_main_conf_t, variables_hash_max_size), null }, ......
从上面第三行可以看到,variables_hash_max_size
指令是在 main 块下生效的。
还会有两个回调方法:
char *(*merge_srv_conf)(ngx_conf_t*cf, void *prev, void *conf);
char *(*merge_loc_conf)(ngx_conf_t*cf, void *prev, void *conf);
例如:
static ngx_http_module_t ngx_http_core_module_ctx = { ngx_http_core_preconfiguration, /* preconfiguration */ ngx_http_core_postconfiguration, /* 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 */ };
ngx_http_module_t
这个结构体里面,定义了很多回调方法,最后一个 ngx_http_core_merge_loc_conf
方法,就是制定合并规则的。这个方法定义了两个参数,一个是父配置,一个是子配置:
static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_core_loc_conf_t *prev = parent; ngx_http_core_loc_conf_t *conf = child; ngx_uint_t i; ngx_hash_key_t *type; ngx_hash_init_t types_hash; if (conf->root.data == null) { ......
这个方法表明了从父配置向子配置合并。
listen 指令在 server 块中生效,用来配置监听哪些端口,由这些端口来处理请求。listen 指令的配置如下:
如示例所示,listen 指令可以监听的类型有多种,可以配置监听地址和端口,也可以是仅地址和仅端口,还可以仅监听 ipv6 等等。
一个指令:server_name
server_name 指令是用来配置究竟是哪个 server 来处理我们的请求的。有时候,一个 server_name 中可能会有多个域名,这时候是如何选择的呢?
server_name *.taohui.tech
server_name www.taohui.tech ~^www\d+\.taohui\.tech$;
当 server_name 指令后有多个域名时,会有一个 server_name_in_redirect 的配置,这个配置默认关闭,它使用来控制域名重定向的,也就是这个配置开启之后,请求过来会重定向到主域名访问。
syntax server_name_in_redirect on | off; default server_name_in_redirect off; context http, server, location
还可以用正则表达式创建变量
# 使用 $1/$2 的方式引用变量 server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } }
# 还可以通过加一个 ?<> 的方式来命名变量 server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } }
特殊的配置规则
这里面 default server 有两种指定方式,假如没有配置 default server,那么第一个 server 块就会成为 default server,如果 listen 中配置了 default,那么就会由配置的块进行处理。
关注公众号回复 nginx 领取知识图谱
如对本文有疑问, 点击进行留言回复!!
linux下文本编辑器vim的使用方法(复制、粘贴、替换、行号、撤销、多文件操作)
网友评论