nginx map指令是启动时构建o(1)查表结构的高效变量映射机制,必须置于http块顶层、server之前;依赖default分支防空值,源变量需稳定字符串型(如$uri、$http_user_agent),输出值须与proxy_pass等指令闭环使用。

Nginx 的 map 指令是实现轻量、高效、可维护动态路由分流的核心机制。它不运行时计算,不依赖 if 或正则匹配开销,而是在启动时构建查表结构,请求到达时仅做 O(1) 字符串查找——这才是生产环境该用的方式。
必须写在 http 块顶层,否则直接报错
所有 map 块只能出现在 http { } 大括号内,且必须在 server 和 upstream 定义之前(通常放在 include 之后、upstream 之前)。写进站点配置(如宝塔的 vhost 文件)或嵌套在 server 里,Nginx 启动会提示 unknown directive "map"。
- 正确位置示例:
/etc/nginx/nginx.conf中的http块开头部分 - map 是变量注册行为,不是条件执行逻辑;它不参与请求处理流程,只提供一个随时可查的变量
- 每个 map 必须有
default分支,否则未匹配时变量为空,可能引发502 Bad Gateway
选对源变量:IP、路径、方法、Header、参数都可驱动分流
源变量决定分流依据,必须是字符串型且值稳定。常见组合如下:
-
客户端 IP:直连用
$remote_addr;经 CDN/代理需先配set_real_ip_from+real_ip_header X-Forwarded-For,再用$realip_remote_addr -
请求路径:用
$uri(解码后、无参数)做精确路由;$request_uri保留原始编码和参数,适合透传场景 -
HTTP 方法:直接用内置变量
$request_method,区分读写最自然 -
请求 Header:如
$http_x_env、$http_user_agent,注意自动转小写,空值走 default -
URL 参数:如
$arg_token、$arg_version,无需手动解析,Nginx 自动提取
输出值要能被 proxy_pass 或缓存指令直接使用
map 本身不转发、不缓存、不拒绝,它只生成一个字符串变量。这个变量必须与后续指令形成闭环:
- 用于
proxy_pass http://$backend/:右侧值必须是已声明的upstream名称,且严格一致(支持下划线,不支持短横线) - 用于缓存控制:
proxy_cache $cache_zone和proxy_cache_key "$host$uri$device",让不同设备/路径生成独立缓存项 - 用于权限控制:配合
if ($allowed = "0") { return 405; },但仅限 location 内简单判断,避免复杂逻辑 - 用于静态资源路径:
root /var/www/$device;,需提前建好对应目录,否则 404
匹配细节决定成败:顺序、大小写、正则写法
map 匹配按从上到下顺序执行,首个成功即终止。几个关键细节常被忽略:
- 正则匹配必须加
~(区分大小写)或~*(不区分),如~* mobile;漏掉波浪线就变成精确字符串匹配 - 长路径规则放前面,例如
/api/v1/users/要在/api/v1/之前,否则被截断 - CIDR 段匹配推荐用
map $realip_remote_addr $backend+192.168.1.0/24 "internal_cluster";,比正则更高效、更清晰 - 地理信息匹配(如
$geoip2_data_country_code)必须是全大写 ISO 码(CN),cn或China都不匹配











