在CentOS 6.9 x86_64的nginx 1.12.2上开启标准模块ngx_http_map_module实录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tao_627/article/details/78995590
介绍
默认情况下,nginx会加载标准模块ngx_http_map_module(或称ngx_map),除非人为的在configure时添加--without-http_map_module选项。
ngx_http_map_module模块可以创建变量,这些变量的值与另外的变量值相关联。允许分类或者同时映射多个值到多个不同值并储存到一个变量中,map指令用来创建变量,但是仅在变量被读取的时候执行计算映射操作,对于处理没有引用变量的请求时,根本不会执行如何无用的计算,所以这个模块并没有性能上的缺失。
Nginx 的这个map指令就可以用于定义两个 Nginx 变量之间的映射关系,或者说是函数关系。
显然,ngx_map 模块认为变量间的映射计算足够昂贵,需要自动将因变量的计算结果缓存下来,这样在当前请求的处理过程中如果再次读取这个因变量,Nginx 就可以直接返回缓存住的结果,而不再调用该变量的“取处理程序”再行计算了。
类似 ngx_map 模块,标准的 ngx_geo 等模块也一样使用了变量值的缓存机制。map 指令只能在 http 块中使用。

很多 Nginx 新手都会担心如此“全局”范围的 map 设置会让访问所有虚拟主机的所有 location 接口的请求都执行一遍变量值的映射计算,然而事实并非如此。前面我们已经了解到 map 配置指令的工作原理是为用户变量注册 “取处理程序”,并且实际的映射计算是在“取处理程序”中完成的,而“取处理程序”只有在该用户变量被实际读取时才会执行(当然,因为缓存的存在,只在请求生命期中的第一次读取中才被执行),所以对于那些根本没有用到相关变量的请求来说,就根本不会执行任何的无用计算。

这种只在实际使用对象时才计算对象值的技术,在计算领域被称为“惰性求值”(lazy evaluation)。提供“惰性求值” 语义的编程语言并不多见,最经典的例子便是 Haskell. 与之相对的便是“主动求值” (eager evaluation)。我们有幸在 Nginx 中也看到了“惰性求值”的例子,但“主动求值”语义其实在 Nginx 里面更为常见,例如下面这行再普通不过的 set 语句:
set $b "$a,$a";
这里会在执行 set 规定的赋值操作时,“主动”地计算出变量 $b 的值,而不会将该求值计算延缓到变量 $b 实际被读取的时候。

模块指令说明
map
语法: map $var1 $var2 { ... }
默认值: —
配置段: http
map为一个变量设置的映射表。映射表由两列组成,依次是匹配模式和对应的值。
在 map 块里的参数指定了源变量值和结果值的对应关系。
匹配模式可以是一个简单的字符串或者正则表达式,使用正则表达式要用('~')。
一个正则表达式如果以 “~” 开头,表示这个正则表达式对大小写敏感。以 “~*”开头,表示这个正则表达式对大小写不敏感。
map $http_user_agent $agent {
    default "";
    ~curl curl;
    ~*apachebench" ab;
}
正则表达式里可以包含命名捕获和位置捕获,这些变量可以跟结果变量一起被其它指令使用。
map $uri $value {
    /ttlsa_com                   /index.php;
    ~^/ttlsa_com/(?<suffix>.*)$  /boy/;
    ~/fz(/.*)                    /index.php?;                           
}
注意:
不能在map块里面引用命名捕获或位置捕获变量。如~^/ttlsa_com/(.*)  /boy/$1; 这样会报错nginx: [emerg] unknown  variable。
如果源变量值包含特殊字符如‘~’,则要以‘\’来转义。
map $http_referer $value {
    Mozilla    111;
    \~Mozilla  222;
}
结果变量可以是一个字符串也可以是另外一个变量。
map $num $limit {
    1   $binary_remote_addr;
    0   "";
}
map指令有三个参数:
default: 指定如果没有匹配结果将使用的默认值。当没有设置default,将会用一个空的字符串作为默认的结果。
hostnames: 允许用前缀或者后缀掩码指定域名作为源变量值。这个参数必须写在值映射列表的最前面。
include file: 包含一个或多个含有映射值的文件。
volatile:暗示变量不能被缓存。

map $http_host $name {
    hostnames;

    default       0;

    example.com   1;
    *.example.com 1;
    example.org   2;
    *.example.org 2;
    .example.net  3;
    wap.*         4;
}

map $http_user_agent $mobile {
    default       0;
    "~Opera Mini" 1;
}
如果匹配到多个特定的变量,如掩码和正则同时匹配,那么会按照下面的顺序进行选择:
1. 没有掩码的字符串
2. 最长的带前缀的字符串,例如: “*.example.com”
3. 最长的带后缀的字符串,例如:“mail.*”
4. 按顺序第一个先匹配的正则表达式 (在配置文件中体现的顺序)
5. 默认值

map_hash_bucket_size
语法: map_hash_bucket_size size;
默认值: map_hash_bucket_size 32|64|128;
配置段: http
指定一个映射表中的变量在哈希表中的最大值,这个值取决于处理器的缓存。

map_hash_max_size
语法: map_hash_max_size size;
默认值: map_hash_max_size 2048;
配置段: http
设置映射表对应的哈希表的最大值。

实例一
http {
    map $args $foo {
        default     0;
        debug       1;
    }
 
    server {
        listen 8087;
        server_name localhost;
 
        location /test {
            set $orig_foo $foo;
            set $args debug;
            echo "orginal foo: $orig_foo";
            echo "foo: $foo";
        }
    }
}

curl -v 'http://localhost:8087/test'


curl -v 'http://localhost:8087/test?debug'

实例二

http {
    map $http_user_agent $agent {
    	~curl curl;
    	~*chrome chrome;
    }

    server {
        listen       8085;
        server_name  localhost;
 
        location /hello {
 			default_type text/plain;
 			echo http_user_agent: $http_user_agent;
 			echo agent: $agent;
 		}
 	}
}

curl -v 127.0.0.1:8085/hello


curl -v 127.0.0.1:8085/hello --user-agent Chrome


curl -v 127.0.0.1:8085/hello --user-agent Safari

实例三

http {
 	map $uri $match {
        ~^/hello/(.*) http://www.ttlsa.com/;
 	}

 	server {
        listen       8086;
        server_name  localhost;
 
        location /hello {
            default_type text/plain;
            echo uri: $uri;
            echo match: $match;
            echo capture: $1;
            echo new: $match$1;
        }
 	}
}
curl -v http://127.0.0.1:8086/hello/aaa/bbb

参考文献
[1].http://www.ttlsa.com/nginx/using-nginx-map-method/
[2].http://www.ttlsa.com/nginx/nginx-var-4/

[3].http://nginx.org/en/docs/http/ngx_http_map_module.html


猜你喜欢

转载自blog.csdn.net/tao_627/article/details/78995590
今日推荐