之前的两篇文章 Nginx 变量介绍[1]以及利用 Nginx 变量做防盗链[2] 讲的是 Nginx 有哪些变量以及一个常见的应用。那么如此灵活的 Nginx 怎么能不支持自定义变量呢,今天的文章就来说一下自定义变量的几个模块以及 Nginx 的 keepalive 特性。
通过映射新变量提供更多的可能性:map 模块
- 功能:基于已有变量,使用类似 switch {case: … default: …} 的语法创建新变量,为其他基于变量值实现功能的模块提供更多的可能性
- 模块:
ngx_http_map_module
默认编译进 Nginx,通过--without-http_map_module
禁用
指令
Syntax: map string $variable { ... }
Default: —
Context: http
Syntax: map_hash_bucket_size size;
Default: map_hash_bucket_size 32|64|128;
Context: http
Syntax: map_hash_max_size size;
Default: map_hash_max_size 2048;
Context: http
我们主要看一下 map string $variable { ... }
这个指令。所谓类似 switch case 的语法是指,string 的值可以有多个,可以根据 string 值的不同,来给 $variable 赋不同的值。
规则
- 已有变量:string 需要是已有的变量,可以分为下面这三种情况
- 字符串
- 一个或者多个变量
- 变量与字符串的组合
- case 规则:{...} 内的匹配规则需要遵循以下规则,尤其是要注意当使用 hostnames 指令时,与 server name 的匹配规则是一致的,可以看之前的文章 Nginx 的配置指令[3]
- 字符串严格匹配
- 使用 hostnames 指令,可以对域名使用前缀 * 泛域名匹配
- ~ 和 ~* 正则表达式匹配,后者忽略大小写
- default 规则
- 没有匹配到任何规则时,使用 default
- 确实 default 时,返回空字符串给新变量
- 其他
- 使用 include 语法提升可读性
- 使用 volatile 禁止变量值缓存
大家看到上面这些规则可能都有些晕,废话不多说,直接来看一个实战配置文件就懂了。
实战
这里我们有一个配置文件,在这个文件里面我们定义了两个 map 块,分别配置了两个变量,和mobile,$name 中包含 hostnames 指令。
map $http_host $name {
hostnames;
default 0;
~map\.ziyang\w+\.org.cn 1;
*.ziyang.org.cn 2;
map.ziyang.com 3;
map.ziyang.* 4;
}