worker_processes auto;
...
stream {
map $remote_addr $dynamic_backend
^(.*)\.(.*)\.(.*)\.*[02468]$ "test1"; //ip最后一位是偶数
^(.*)\.(.*)\.(.*)\.*[13579]$ "test2"; //ip最后一位是奇数
//一个正则表达式如果以 “~” 开头,表示这个正则表达式对大小写敏感。以 “~*”开头,表示这个正则表达式对大小写不敏感。
~curl curl;
~*apachebench" ab;
//正则表达式里可以包含命名捕获和位置捕获,这些变量可以跟结果变量一起被其它指令使用。
/abc /index.php;
~^/teacher/(?<suffix>.*)$ /boy/;
~/fz(/.*) /index.php?fz=1;
xxx.xxx.xxx.xx3 "test3";
default "test1"
upstream test1 {
server xxx.xxx.xxx.xxx:80;
}
upstream test2 {
server xxx.xxx.xxx.xxx:80;
}
upstream test3 {
server xxx.xxx.xxx.xxx:80;
}
server {
listen 80;
proxy_pass $dynamic_backend
}
}
http {
...
}
==注意:不能在map块里面引用命名捕获或位置捕获变量。如~^/qupeicom/(.*) /peiyin/$1; 这样会报错nginx: [emerg] unknown variable==
==注意二:如果源变量值包含特殊字符如‘~’,则要以‘\’来转义。==
map $http_referer $value {
Mozilla 111;
\~Mozilla 222;
}
源变量匹配表达式对应的结果值可以是一个字符串也可以是另外一个变量。
map $http_referer $value {
Mozilla 'chrom';
\~safity $http_user_agent;
实例(一)
使用 map 来实现允许多个域名跨域访问的问题
如果是允许单域名跨域访问直接配置就行了,如下:
# 这些配置可以写在 http{} 或者 server{} 都是支持的。
add_header Access-Control-Allow-Origin "http://www.tutu.com";
add_header Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, DELETE";
add_header Access-Control-Max-Age "3600";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept;
#!/bin/bash
# 上面的配置只允许 http://www.tutu.com 跨域访问,如果要支持所有域名都可以跨域调用该站。 把上面一行改成这样,不过不推荐这样做,因为不安全
add_header Access-Control-Allow-Origin "*";
如果不想允许所有,但是又需要允许多个域名,那么就需要用到 map
map $http_origin $corsHost {
default 0;
"~http://www.haibakeji.com" http://www.haibakeji.com;
"~http://m.haibakeji.com" http://m.haibakeji.com;
"~http://wap.haibakeji.com" http://wap.haibakeji.com;
}
server
{
listen 80;
server_name www.haibakeji.com;
root /nginx;
location /
{
add_header Access-Control-Allow-Origin $corsHost;
}
}
实例(二)
使用源变量(通常是 nginx 内置变量)匹配一些规则,创建自定义变量,然后在页面输出. 这通常在调试的时候非常有用
http {
map $uri $match {
~^/hello/(.*) http://www.hello.com/;
}
server {
listen 8080;
server_name test.hello.com;
location /hello {
default_type text/plain;
echo uri: $uri;
echo match: $match;
echo capture: $1;
echo new: $match$1;
}
map 涉及的性能问题
大家可能会有一个问题,map 既然只能用在 http 段,这是全局的啊。 这个设置会让访问所有虚拟主机的请求都要匹配并设置一遍变量的值,然而事实并非如此,对于没有用到相关变量的请求来说,并不会执行 map 操作。 就没有性能上的损失。
匹配优先级问题
如果匹配到多个特定的变量,如掩码和正则同时匹配,那么会按照下面的顺序进行选择:
没有掩码的字符串
最长的带前缀的字符串,例如: “*.example.com”
最长的带后缀的字符串,例如:“mail.*”
按顺序第一个先匹配的正则表达式 (在配置文件中体现的顺序)
默认值
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
设置映射表对应的哈希表的最大值。