Nginx流量镜像通过mirror指令非侵入式复制HTTP请求至镜像服务,原始请求不受影响;需启用mirror_request_body on支持请求体,异步发送且失败不干扰主流程,配合采样、头部隔离与超时控制保障稳定性。

在 Nginx 中实现流量镜像(Traffic Mirroring),本质是将生产请求**非侵入式地复制一份**,转发到镜像服务(如备份集群、灰度环境或流量回放系统),而**原始请求仍按正常流程处理**,不影响线上业务。Nginx 自身不支持“完全等价”的请求镜像(比如保持原始 TCP 连接、精确复现超时/重试行为),但可通过 mirror 指令实现 HTTP 层的请求副本投递,这是最常用且实用的方式。
启用 mirror 模块并配置基础镜像规则
Nginx 1.13.4+ 内置 ngx_http_mirror_module,无需额外编译。只需在 location 块中使用 mirror 指令指定镜像目标:
- 镜像请求默认以
GET方法发起,且只携带原始请求的 URI、查询参数和请求头(不含请求体);若需镜像带 body 的 POST/PUT 请求,必须显式启用mirror_request_body on(Nginx 1.19.0+) - 镜像请求是异步发送的,失败不会影响主请求响应;建议为镜像 upstream 配置独立的
proxy_next_upstream和超时策略,避免拖慢主链路 - 示例配置片段:
upstream mirror_backend {
server 192.168.10.100:8080;
server 192.168.10.101:8080;
}
<p>server {
listen 80;
location /api/ {</p><h1>主上游(真实业务集群)</h1><pre class="brush:php;toolbar:false;"> proxy_pass http://main_backend;
# 启用镜像(触发复制)
mirror /mirror;
mirror_request_body on; # 确保 POST/JSON 等 body 被镜像
# 镜像子请求专用 location
location = /mirror {
internal; # 仅限内部调用,禁止外部直接访问
proxy_pass http://mirror_backend$request_uri;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Mirror-Timestamp $msec;
proxy_ignore_client_abort on; # 客户端断开时,仍完成镜像发送
}
}}
控制镜像范围与采样率
全量镜像可能压垮镜像服务,通常需按需限流或采样:
- 用
map指令结合随机数实现百分比采样,例如只镜像 5% 的请求:
map $request_id $mirror_flag {
default "";
~^(?!(.*)) ""; # 占位
}
<h1>利用 $remote_addr + $msec 构造简单哈希,实现近似均匀采样</h1><p>map $msec$remote_addr $should_mirror {
~^[0-9]{13}([0-4])$ 1; # 末位 0–4 → 50%;可改为 [0-0] 实现 10%
default 0;
}</p><p>server {
location /api/ {
mirror @mirror_zone;
mirror_request_body on;</p><pre class="brush:php;toolbar:false;"> proxy_pass http://main_backend;
}
location @mirror_zone {
internal;
if ($should_mirror = 0) { return 403; }
proxy_pass http://mirror_backend;
}}
- 更精准的采样可用
split_clients或第三方模块(如nginx-module-sts),但原生方案已满足多数场景
确保镜像请求不干扰主业务
关键在于隔离性与可观测性:
-
头部隔离:镜像请求应添加自定义 header(如
X-Mirror: true),让后端识别并跳过写操作、鉴权、日志落盘等副作用逻辑 -
响应忽略:镜像子请求的响应体被自动丢弃,无需
proxy_buffering off;但建议设置较短超时(proxy_read_timeout 3s)防止堆积 -
错误静默:镜像失败不报错,也不记录 error log(除非调试需要)。可通过
error_log /dev/null warn;在location /mirror中关闭冗余日志 -
监控指标:利用
mirror指令触发的子请求会生成 access log,可单独配置 log_format 统计镜像成功率、延迟等
注意事项与常见问题
该方案不是“网络包镜像”,而是应用层请求复制,有明确边界:
- 不镜像 WebSocket、HTTP/2 push、gRPC 流式请求;仅适用于常规 HTTP/1.x 请求
- 镜像请求的
Host头默认继承原始值,如需修改,用proxy_set_header Host mirror.example.com; - 若主请求含敏感 Cookie 或 Authorization,需在
/mirrorlocation 中清除:proxy_set_header Cookie "";、proxy_set_header Authorization ""; - 镜像服务本身需具备幂等性设计——因镜像请求可能重复、延迟、乱序到达











