流量镜像 (Traffic Mirroring),通常用于进行应用版本的测试,它将实时流量的副本发送给被镜像的服务。采用这种方法,可以搭建一个与原环境类似的环境以进行测试,从而提前发现问题。由于镜像流量存在于主服务关键请求路径带外,终端用户在测试全过程不会受到影响。
Nginx的流量镜像是只复制镜像,发送到配置好的后端,但是后端响应返回到nginx之后,nginx是自动丢弃掉的,这个特性就保证了镜像后端的不管任何处理不会影响到正常客户端的请求。
采用nginx作为流量镜像,需要nginx支持 nginx_http_mirror_module
模块。
在 nginx 1.13.4 之后的怎么自己带 该模块不需要额外安装mirror模块
Nginx复制所有请求流量
upstream service_a {
server 10.10.1.2:8080;
}
upstream service_b {
server 10.10.1.3:8080;
}
server {
server_name mirror.kpl.dev;
listen 80;
location / {
mirror /mirror; # mirror 指令制定镜像 uri 为 /mirror
proxy_pass http://service_a;
}
location = /mirror {
internal; # internal 指定此 location 只能被“内部的”请求调用,外部的调用请求会返回 ”Not found” (404)
rewrite ^/mirror(.*)$ $1$request_uri break;
proxy_pass http://service_b$request_uri;
}
}
只允许GET请求
location / {
mirror /mirror; # mirror 指令制定镜像 uri 为 /mirror
mirror_request_body off; # off 为不镜像请求body部分
proxy_pass http://service_a;
}
location = /mirror {
# 判断请求方法,不是GET返回403
if($request_method != GET) {
return 403;
}
internal; # internal 指定此 location 只能被“内部的”请求调用,外部的调用请求会返回 ”Not found” (404)
rewrite ^/mirror(.*)$ $1$request_uri break;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_pass http://service_b$request_uri;
}
拷贝流量放大
将流量放大,只需要增加多个, mirror
就好
location / {
mirror /mirror; # mirror 指令制定镜像 uri 为 /mirror
mirror /mirror; # 每多加一份mirror,流量放大一倍
proxy_pass http://service_a;
}location = /mirror {
# 判断请求方法,不是GET返回403
if($request_method != GET) {
return 403;
}
internal; # internal 指定此 location 只能被“内部的”请求调用,外部的调用请求会返回 ”Not found” (404)
rewrite ^/mirror(.*)$ $1$request_uri break;
proxy_pass http://service_b$request_uri;
}
如果mirror_request_body
或者proxy_pass_request_body
设置为 off
,则Content-Length
必须设置为""
因为nginx(mirror_request_body)
处理post请求时,会根据Content-Length
获取请求体,
如果Content-Length
不为空,而由于mirror_request_body
或者proxy_pass_request_body
设置为off
,
处理方以为post
有内容,当request_body
中没有,处理方会一直等待至超时,则前者为off
,nginx会报upstream请求超时。