map模块用于根据$server_port动态映射后端地址,必须在http块中定义,通过proxy_pass引用$backend实现端口分流,推荐精确匹配端口并设default兜底。

理解 map 模块的核心作用
map 是 Nginx 的一个内置模块(默认启用),用于根据某个变量的值,映射出另一个变量的值。它不是用来直接做代理转发的,而是为后续指令(比如 proxy_pass)提供动态值的“计算层”。关键点在于:map 块必须定义在 http 上下文中,且其结果变量可在 server 或 location 中使用。
为什么用 $server_port 而不是 $remote_port
常见误区是想用客户端发起连接的端口($remote_port),但实际业务中,用户访问的是 Nginx 监听的端口(如 80、443、8080),Nginx 自己知道当前请求落在哪个监听端口上——这个才是可靠的分流依据。$server_port 表示 Nginx 接收该请求时所用的监听端口号,稳定、可预测、无需额外解析。
配置步骤:从定义映射到生效代理
以下是一个完整、可直接测试的配置片段:
1. 在 http 块中定义端口到后端地址的映射:
- 每个
map块以map $server_port $backend开头,表示把端口映射为一个叫$backend的变量 - 用
default设定兜底值,避免未匹配端口导致变量为空 - 支持精确匹配(如
8080)和正则(需加波浪线~),但端口号推荐用精确值更清晰
http {
map $server_port $backend {
default "127.0.0.1:9001";
80 "127.0.0.1:9001";
443 "127.0.0.1:9002";
8080 "127.0.0.1:9003";
8443 "127.0.0.1:9004";
}
server {
listen 80;
listen 443 ssl;
listen 8080;
listen 8443 ssl;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
2. 验证与调试技巧:
- 修改配置后运行
nginx -t确保语法正确 - 用
curl -v http://localhost:8080/和curl -v https://localhost:8443/分别测试,观察后端响应头或日志确认是否命中预期服务 - 临时加一行
add_header X-Backend $backend;到 location 中,响应头里就能看到 Nginx 实际选中的后端地址
进阶提示:结合 SSL 和多域名更灵活分流
如果同一端口(如 443)要按域名再细分,可组合使用:map $server_port:$host $backend { ... },例如 "443:api.example.com" "127.0.0.1:9010";。
注意:复合 key 必须确保变量间分隔符不会出现在任一变量值中(冒号较安全),且所有可能组合都要覆盖或设好 default。











