Nginx 的 map 指令可基于 HTTP 方法实现读写分离:将 GET/HEAD/OPTIONS 映射至 read_pool,POST/PUT/PATCH/DELETE 映射至 write_pool,默认回退 read_pool;配合 upstream 物理隔离后端,并在 location 中用 proxy_pass http://$backend/ 动态转发,高效安全。

用 Nginx 的 map 指令做基于 HTTP 方法的后端分流,本质是把请求动词(GET/POST/PUT/DELETE 等)映射成一个变量值,再在 proxy_pass 或条件判断中直接引用。它轻量、高效、无需重写逻辑,是读写分离场景下最推荐的配置方式之一。
在 http 块中定义方法到后端的映射关系
所有 map 块必须放在 http 块顶层,不能嵌套在 server 或 location 里。核心是按语义分组:读操作走只读集群,写操作走主写集群。
- GET、HEAD、OPTIONS 属于安全幂等读请求,映射到
read_pool - POST、PUT、PATCH、DELETE 属于数据变更操作,映射到
write_pool -
default值建议设为read_pool,避免未知方法意外打到写库
示例配置:
map $request_method $backend {
default "read_pool";
GET "read_pool";
HEAD "read_pool";
OPTIONS "read_pool";
POST "write_pool";
PUT "write_pool";
PATCH "write_pool";
DELETE "write_pool";
}配合 upstream 实现物理后端隔离
map 只负责“选名字”,真正路由靠 upstream 块定义的服务器组。读写后端应物理隔离,避免资源争抢和故障扩散。
-
read_pool可配置多个从节点,支持 weight 和健康检查,提升吞吐与容错 -
write_pool通常单点部署或强一致性集群,不建议轮询;如需高可用,可配backup节点 + 主动健康检查
示例:
upstream read_pool {
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080 max_fails=2 fail_timeout=30s;
}
<p>upstream write_pool {
server 10.0.1.20:8080;</p><h1>server 10.0.1.21:8080 backup; # 备用主节点</h1><p>}在 location 中完成动态代理转发
location 块内直接使用 $backend 变量,Nginx 会在每次请求时实时解析其值并代入 proxy_pass。这种方式无 if 判断开销,性能优于条件分支。
- 确保
proxy_pass后带斜杠(如http://$backend/),否则路径拼接可能出错 - 记得透传关键头信息,如
Host、X-Real-IP,方便后端日志与鉴权 - 若需更细粒度控制(如某类 POST 仍走读库),可在 map 中结合
$uri或自定义 header 扩展逻辑
示例:
location /api/ {
proxy_pass http://$backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}补充:权限控制与安全兜底
仅靠分流还不够。对敏感接口(如管理后台、删除端点),建议叠加方法级拦截,快速拒绝非法调用。
- 复用同一套 map 逻辑,定义
$allowed_method,将 DELETE/PUT 等设为 "0" - 在对应 location 中用
if ($allowed_method = "0") { return 405; }拦截 - 注意:该 if 仅用于变量比对,不涉及 rewrite,符合 Nginx 官方安全使用规范

















