nginx mirror指令可实现请求全量复制到多个后端,推荐openresty+lua并发分发或nginx-mirror-module多mirror_pass方案,需启用mirror_request_body、设置internal及host头等关键配置。

要让一次客户端请求**同时发给多个后端服务**(不是负载均衡选一个,而是全量复制发送),核心是用 Nginx 的 mirror 指令,它专为无感流量镜像设计,主链路不受影响,镜像失败也不报错、不阻塞。
确认 Nginx 版本并启用 mirror 功能
确保你的 Nginx 是 1.13.4 或更高版本(当前主流发行版基本都满足)。无需编译安装模块,mirror 是内置功能。检查方法:
nginx -v
若版本达标,直接配置即可,不用额外加载模块。
基础镜像配置:一份请求,两个目标
典型场景:主请求走 https://prod-api,同时镜像一份到 https://test-api 和 https://log-collector。Nginx 原生 mirror 只支持单个镜像目标,所以需借助 location 分层 + 多级 mirror 或 第三方模块 实现多目标。推荐两种实用路径:
-
方案一(推荐,原生+简单):用 OpenResty + Lua 实现多目标分发
在/mirror子请求中,用 Lua 脚本并发调用多个后端,例如:
location = /mirror {
internal;
content_by_lua_block {
local http = require "resty.http"
local httpc = http.new()
-- 并行发往两个地址
httpc:request_uri("https://test-api$request_uri", { method = ngx.var.request_method, body = ngx.var.request_body })
httpc:request_uri("https://log-collector$request_uri", { method = ngx.var.request_method, body = ngx.var.request_body })
}
}
-
方案二(更可控):使用 nginx-mirror-module 第三方模块
它原生支持多 mirror_pass,配置简洁:
location /api/ {
proxy_pass https://prod-api;
mirror_match "always" "1"; # 总是镜像
mirror_pass @test_backend;
mirror_pass @log_backend;
}
<p>upstream test_backend { server test-api.example.com; }
upstream log_backend { server log-collector.example.com; }</p>
关键细节必须设置正确
- mirror_request_body on; —— 否则 POST/PUT 请求体不会被复制(仅 Nginx 1.19.0+ 支持)
- proxy_set_header X-Original-URI $request_uri; —— 让镜像服务知道原始路径
- internal; 在镜像 location 中强制限定仅内部调用,防止外部直接访问 /mirror
-
镜像请求默认不带 Host 头,需手动补上:
proxy_set_header Host $host; - 镜像超时或失败时,Nginx 默认静默丢弃,不影响主响应;如需日志记录,可配合
error_log或 Lua 打点
验证与调试建议
- 用 curl 发起一次 POST 请求,主服务和两个镜像服务都要有日志输出,确认都收到
- 临时把镜像目标设为一个本地 Flask 服务(如 8081、8082 端口),便于观察原始请求头和 body 是否完整到达
- 注意 HTTPS 镜像目标需确保 Nginx 已信任其证书,否则会 502;可加
proxy_ssl_verify off;(仅测试环境) - 高并发下建议限制镜像请求数量或加队列缓冲,避免压垮镜像服务











