一、Nginx 镜像功能介绍


Nginx1.13.4 版本开始引入了 ngx_mirror_module 模块:

The ngx_http_mirror_module module (1.13.4) implements mirroring of an original request by creating background mirror subrequests. Responses to mirror subrequests are ignored.

该模块会对原请求进行复制,产生一个镜像的子请求,镜像出来的子请求的响应会被忽略。有了镜像请求后,我们可以将请求引流到其他的服务当中去,比如线上请求引到测试环境,这样,当线上环境出现了问题时,我们就能对其进行排查。

下面是 Nginx 的镜像功能适用的场景:

  • 验证服务是否正常以及服务的性能;
  • 复制真实流量实现服务验证,不必重复造数据,并且不影响线上正常访问;
  • 以真实流量排查线上问题;

Nginx 的镜像功能使用的是 mirror 指令,通过 mirror 指令实现请求的监听和拷贝。



二、Mirror 指令的使用


下面是官方提供的一个简单配置的示例:

location / {
    mirror /mirror;
    proxy_pass http://backend;
}

location = /mirror {
    internal;
    proxy_pass http://test_backend$request_uri;
}

Mirror 功能介绍:

  • 1、Mirror 指令的语法为:mirror uri | off;off 表示关闭镜像功能,而 uri 表示要将原始请求镜像到哪个 uri,可以同时使用多个镜像地址;
  • 2、Mirror 指令可以使用在 httpserverlocation 模块中;
  • 3、Location 模块中的 internal 指令表示该 location 只能被内部的请求调用,外部调用的请求会返回 Not found(404)

除了这些指令外,还可以 通过 mirror_request_body on | off; 来设置是否镜像请求体(默认是开启),同时也可以,下面是一个实际的完整示例:

location / {
    # 指定镜像的 URI,开启请求体镜像
    mirror /mirror;
    mirror_request_body on;
    
    # 设置代理服务器请求头信息
    proxy_pass_header Set-Cookie;
    proxy_set_header  Host  $host;
    proxy_set_header  X-Real-Ip  $remote_addr;
    proxy_set_header  X-Forwarded-For  $remote_addr;
    proxy_set_header  X-Original-URI  $request_uri;
    
    # 代理服务跳转
    proxy_pass http://192.168.56.10:8080;
}

# 镜像跳转的 location 块
location = /mirror {
    # 只能内部调用
    internal;
    
    # 设置代理服务器请求头信息
    proxy_pass_header Set-Cookie;
    proxy_set_header  Host  $host;
    proxy_set_header  X-Real-Ip  $remote_addr;
    proxy_set_header  X-Forwarded-For  $remote_addr;
    proxy_set_header  X-Original-URI  $request_uri;
    
    # 代理服务跳转
    proxy_pass http://192.168.56.12:8080$request_uri;
}

实例介绍:

  • 1、在该实例中,我们对 / 地址的请求进行镜像,镜像的 URL/mirror地址随意起);
  • 2、定义另一个 location 块,监听的地址为镜像的目标地址 /mirror
  • 3、当 / 地址发生请求时,mirror 会将请求拷贝已经传给 location = /mirror {} 块中。

需要注意的是: 请求镜像的 location 快中的代理服务跳转需要在跳转的服务对称后面添加 $request_uri 变量,表示将整个请求地址拷贝过去,如果没有这个变量的话,目标服务器收到的请求地址就会是 /error



三、镜像功能的缺点及解决方案


1、镜像机制的缺点

Nginx 的镜像功能并不只是简单的复制,复制的镜像请求和原始请求是相关联的,若镜像请求没有处理完成,原始请求就会被阻塞。也就是说,如果镜像的子请求出现问题,也会影响原始的请求,所以,开启流量镜像模式做为测试流量时,要认真监控 Nginx 性能指标,发现请求反馈异常要即时处理。

2、解决方案

当不确定镜像请求是否能够处理原始请求的情况,我们可以只复制部分流量到镜像请求当中,比如 10%。流量复制使用的是 split_client 指令,具体的使用方案可以参考官方文档:ngx_http_split_clients_module