Nginx HTTP模块详解
1、动态赋值功能模块
Nginx在核心模块及其他模块中都提供了内置变量,用户可以根据需要灵活调用。在Nginx的模块中除提供了rewrite指令以方便用户对变量进行静态赋值外,还提供了根据请求内容的变化为变量动态赋值的功能。
1.1、根据浏览器动态赋值
模块名称:ngx_http_browser_module
该模块的功能是根据客户端HTTP请求头中的属性字段User-Agent的值,按照用户的指令配置设置变量$modern_browser和$ancient_browser的值。用户可以根据变量$modern_browser和$ancient_browser的值对客户端浏览器进行区分,并对HTTP请求进行不同的处理。该模块的内置配置指令如表所示。
1.1.1、旧浏览器标识指令------ancient_browser

配置样例如下:
bash
http {
ancient_browser 'UCWEB';
}
变量$ancient_browser的值默认为1。
1.1.2、设置旧浏览器变量值指令------ancient_browser_value

配置样例如下:
bash
http {
ancient_browser 'UCWEB';
ancient_browser_value oldweb;
server {
if ($ancient_browser) {
rewrite ^ /${ancient_browser}.html; # 重定向到oldweb.html
}
}
}
1.1.3、新浏览器标识指令------modern_browser

配置样例如下:
bash
http {
modern_browser msie 5.5;
}
- 内置浏览器类型有msie、gecko(由Mozilla基金会维护,Mozilla及Netscape 6后续版本是基于Gecko开发的)、opera、safari、konqueror。
- 当指令值为unlisted时,Nginx在HTTP请求头中的属性字段User-Agent的值为空或无法识别浏览器类型时,设置变量$modern_browser的值为1。
配置样例如下:
bash
http {
modern_browser msie 5.5;
modern_browser unlisted;
}
1.1.4、设置新浏览器变量值指令------modern_browser_value

配置样例如下:
bash
http {
modern_browser msie 5.5;
modern_browser_value newweb;
server {
if ($modern_browser) {
rewrite ^ /${modern_browser}.html;
}
}
}
配置样例如下:
bash
ancient_browser 'UCWEB'; # 必须使用单引号
ancient_browser_value oldweb; # 设置$ancient_browser的值为oldweb
modern_browser_value newweb; # 设置$ancient_browser的值为newweb
modern_browser unlisted; # 设置$modern_browser的值为1, $ancient_browser的值为0
root /opt/nginx-web;
server {
listen 8080;
if ($ancient_browser) {
rewrite ^ /${ancient_browser}.html; # 重定向到oldweb.html
}
if ($modern_browser) {
rewrite ^ /${modern_browser}.html; # 重定向到newweb.html
}
}
1.2、根据IP动态赋值
模块名称:ngx_http_geo_module
该模块的功能是从源变量获取IP地址,并根据设定的IP与对应值的列表对新变量进行赋值。该模块只有一个geo指令,指令格式如下:
bash
geo [源变量]新变量{}
- geo指令的默认源变量是$remote_addr,新变量默认值为空。
- geo指令的作用域只能是http。
该指令的指令值参数如表所示。

配置样例如下:
bash
http{
geo $country {
proxy_recursive; # 启用代理递归查询
default ZZ; # 默认值为ZZ
include conf/geo.conf; # 引入外部列表文件
proxy 192.168.100.0/24; # 上层代理地址为192.168.100.0/24的IP
proxy 2001:0db8::/32; # 上层代理地址为2001:0db8::/32的IP
127.0.0.0/16 US; # 赋值US
127.0.0.1/32 RU; # 赋值RU
10.1.0.0/16 RU; # 赋值RU
192.168.1.0/24 UK; # 赋值UK
}
}
为了加速加载IP来设定变量表,IP地址应按升序填写。
外部文件geo.conf的内容格式如下:
bash
10.2.0.0/16 RU;
192.168.2.0/24 RU;
以地址段形式定义的IP地址中ranges参数的配置样例如下:
bash
http{
geo $country {
ranges; # 使用以地址段的形式定义的IP地址
default ZZ;
10.1.0.0-10.1.255.255 RU;
192.168.1.0-192.168.1.255 UK;
}
}
自定义源变量配置样例如下:
bash
geo $arg_ip $address { # 设置请求参数IP为源变量
default CN;
127.0.0.0/24 US;
127.0.0.10/32 RU;
10.1.0.0/16 RU;
delete 127.0.0.10/32; # 删除127.0.0.10/32的设定
}
server {
listen 8081;
server_name localhost;
charset utf-8;
root /opt/nginx-web;
default_type text/xml;
location / {
rewrite ^ /${address}.html break; # 重定向到$address.html
}
}
1.3、根据IP动态获取城市信息
模块名称:ngx_http_geoip_module
该模块的功能是将客户端的IP地址与MaxMind数据库中的城市地址信息进行比对,然后将对应的城市地址信息赋值给内置变量。该模块的配置指令如表所示。
- 国家信息数据库指令

- 城市信息数据库指令

- 机构信息数据库指令

- 上层代理IP指令

- 代理递归查询IP指令


geo内置变量如表所示。

配置样例如下:
bash
geoip_country /usr/share/GeoIP/GeoIP.dat;
geoip_city /usr/share/GeoIP/GeoIPCity.dat;
geoip_org /usr/share/GeoIP/GeoIPASNum.dat;
geoip_proxy 192.168.2.145;
geoip_proxy_recursive on;
server {
listen 8081;
server_name localhost;
charset utf-8;
root /opt/nginx-web;
default_type text/xml;
location / {
if ( $geoip_country_code ) {
rewrite ^ /$geoip_country_code/ break; # 重定向到$geoip_country_cod目录
}
}
}
1.4、比例分配赋值
模块名称:ngx_http_split_clients_module
该模块会按照配置指令将一个0~232之间的数值根据设定的比例分割为多个数值范围,每个数值范围会被设定一个对应的给定值。用户每次请求时,指定的字符串会被计算出一个数值,该模块会将该数值所在范围对应的给定值赋值给配置中定义的变量。该功能常用来按照用户的来源IP进行访问流量分流。该指令语法格式如下:
bash
split_clients 字符串 新变量{}
配置样例如下:
bash
split_clients "${remote_addr}AAA" $source { # "${remote_addr}AAA"会被计算出一个数值
0.5% .one; # 数值在0~21474835之间,$source被赋值".one"
80.0% .two; # 数值在21474836~3435973836之间,$source被赋值".two"
* ""; # 数值在3435973837~4294967295, $source被赋值""
}
server {
location / {
index index${source}.html;
}
}
- 该指令会将一个2的32次幂计算的值(数值范围为0~4294967295)按照指令域中的比例进行分割。
- 客户端每次请求时,会将指定字符串使用MurmurHash2算法计算出一个0~232(0~4 294 967 295)之间的数值,该模块会将该数值所在范围对应的给定值赋值给配置中定义的变量。
- 指定的字符串可以是Nginx内置变量。
1.5、变量映射赋值
模块名称:ngx_http_map_module
该模块的功能是在客户端每次请求时,Nginx按照map指令域中源变量的当前值把设定的对应值赋值给新变量。该指令语法格式如下:
bash
map 源变量 新变量{}
map指令值参数如表所示。


配置样例如下:
bash
map $remote_addr $name {
hostnames;
default 0;
example.com 1;
*.example.com 1; # 主机名前缀
wap.* 4; # 主机名后缀
include hostmap.conf;
}
- map指令只能编辑在http指令域中。
- map指令域中指定了源变量为不同值时与新变量值的对应关系。
- map指令域中源变量的值可以是字符串或正则表达式的匹配。
- map指令域中对源变量的值进行正则表达式匹配时,以"~"开头表示对源变量值的匹配,区分大小写,以"*"开头表示对源变量值的匹配不区分大小写。
bash
map $http_user_agent $mobile {
"~Opera Mini" 1;
"*UCWEB" 2;
}
map指令域中对源变量的值进行正则表达式匹配时,可以对源变量值进行正则捕获。
bash
map $uri $new_uri {
~^/user/(.*) ucenter; # 若URI为/user/login时,$new_uri被赋值为"ucenter"
}
server {
listen 8080;
location /user {
default_type text/plain;
rewrite ^ /$new_uri/$1; # rewrite到/ucenter/login
}
location /ucenter {
index index.html;
}
}
若源变量值中包含特殊字符串"~",可以用"~"进行转义。
bash
map $http_referer $flag {
Mozilla 111;
\~Mozilla 222;
}
新变量的值可以是字符串,也可以是另一个变量。
bash
map $http_referer $value {
Mozilla 'chrom';
\~safity $http_user_agent;
}
map指令域中,当源变量值存在相同匹配项时,匹配顺序如下:
-
1)完全匹配的字符串。
-
2)有主机前缀的最长字符串。
-
3)有主机后缀的最长字符串。
-
4)在指令域中按自上而下顺序最先匹配到的正则表达式。
-
5)default参数给定的默认值。
-
map哈希表大小指令

-
map哈希桶大小指令

配置样例如下:
bash
map $remote_addr $dir {
default www; # 设置默认目录为www
include conf.d/remoteip.list;# 以外部文件形式编写IP及对应新变量赋值列表
}
server {
listen 8080;
root /opt/nginx-web/$dir;
index index.html;
}
remoteip.list文件内容:
192.168.2.145 blue; # 源IP为192.168.2.145时,map的新变量值为blue
192.168.2.100 green; # 源IP为192.168.2.100时,map的新变量值为green