Nginx 1.13.4+ 原生支持 mirror 指令实现请求镜像,需在 location 中配置 mirror 指向 internal 的镜像路径,并确保主 proxy_pass 在 mirror 之后;旧版本需第三方模块或外部重放方案。

Nginx 本身不直接支持“镜像请求复制”(即把同一请求同时发给两个后端,只返回主后端响应,另一份静默转发),但可以通过 location 配合 mirror 指令(Nginx Plus 或开源版 1.13.4+)实现真正的请求镜像。若使用较老版本或纯开源 Nginx,需借助第三方模块(如 nginx-mirror-module)或变通方案(如日志 + 外部工具重放)。以下以主流、原生支持的方式为主说明。
确认 Nginx 版本并启用 mirror 模块
从 1.13.4 起,mirror 是官方内置模块(无需编译选项),但默认可能未启用。执行 nginx -V 2>&1 | grep -o with-http_mirror_module,若无输出,需重新编译并添加 --with-http_mirror_module。Docker 官方镜像或主流发行版包(如 Ubuntu 22.04+ 的 nginx-core)通常已包含。
基础镜像配置:单 location 内复制请求
在 location 块中使用 mirror 指令指定镜像目标,该目标会收到完全相同的请求(含方法、URI、头、正文),但其响应被忽略;主请求仍按常规流程处理(proxy_pass 等)。
示例配置:
location /api/ {
# 主代理到生产服务
proxy_pass http://backend-prod;
<pre class="brush:php;toolbar:false;"># 同时镜像一份到测试环境(路径保持不变)
mirror /mirror-api;
mirror_request_body on; # 默认开启,确保请求体也被镜像
# 镜像目标的内部 location(不对外暴露)
location = /mirror-api {
internal; # 仅限内部调用,禁止外部访问
proxy_pass http://backend-staging$request_uri;
proxy_pass_request_body on;
proxy_set_header Host $host;
proxy_set_header X-Original-URI $request_uri;
}
}
注意:mirror 指令必须放在 proxy_pass 之前;internal 是必需的安全限制;$request_uri 保留原始查询参数和路径。
进阶控制:按条件镜像与排除敏感路径
镜像并非总要全量开启。可通过 mirror 指令配合变量或 if 判断实现条件触发(注意:if 在 location 中受限,推荐用 map 提前定义):
- 用
map根据请求头或 URI 设置镜像开关:
map $http_x-enable-mirror $mirror_target {
"1" "/mirror-api";
default "";
}
# ……
location /api/ {
mirror $mirror_target;
proxy_pass http://backend-prod;
# ……
}
- 避免镜像登录、支付等敏感接口,可在 location 中用正则排除:
location ~ ^/api/(?!login|pay|admin) {
mirror /mirror-api;
proxy_pass http://backend-prod;
# ……
}
验证与调试要点
镜像请求默认不参与主响应流程,因此无法直接从客户端看到效果。验证方式包括:
- 在
/mirror-api对应的后端(如 staging)开启详细访问日志,确认收到请求及完整头信息; - 检查 Nginx error 日志,若出现
mirror: invalid URL或upstream timed out,说明镜像目标不可达或超时——建议为镜像单独设置宽松超时(proxy_read_timeout 60;放在/mirror-api块内); - 使用
curl -v -H "X-Enable-Mirror: 1" http://yourdomain/api/test测试条件镜像是否生效。
不复杂但容易忽略:镜像请求共享主请求的连接池与缓冲区设置,若镜像后端响应慢,可能间接影响主请求性能(尤其高并发时),建议对镜像路径单独调优或使用异步队列解耦。










