Nginx http_mirror_module 实现流量复制
需求
将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如:
-
可以验证功能是否正常,以及服务的性能;
-
用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问;
-
这跟灰度发布还不太一样,镜像流量不会影响真实流量;
-
可以用来排查线上问题;
-
重构,假如服务做了重构,这也是一种测试方式;
为了实现流量拷贝,Nginx提供了ngx_http_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.
Example Configuration
location / { mirror /mirror; proxy_pass http://backend; } location = /mirror { internal; proxy_pass http://test_backend$request_uri; }
Directives
Syntax: | mirror |
---|---|
Default: | |
Context: | http , server , location |
Sets the URI to which an original request will be mirrored. Several mirrors can be specified on the same level.
Syntax: | mirror_request_body |
---|---|
Default: | |
Context: | http , server , location |
Indicates whether the client request body is mirrored. When enabled, the client request body will be read prior to creating mirror subrequests. In this case, unbuffered client request body proxying set by the proxy_request_buffering, fastcgi_request_buffering, scgi_request_buffering, and uwsgi_request_buffering directives will be disabled.
location / { mirror /mirror; mirror_request_body off; proxy_pass http://backend; } location = /mirror { internal; proxy_pass http://log_backend; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; }
http_mirror_module功能和特性
mirror模块可以帮助我们创建一份镜像流量,比如在生产环境下处理一些请求,这些请求可能要同步的copy一份到我的测试环境当中或者开发环境当中做处理,mirror模块就可以实现。
每当我们的请求到了nginx之后,可以生成子请求。这个子请求可以通过反向代理去访问我们其他的环境,比如我们的测试环境。而对测试环境和其他环境返回的内容我们是不做处理的,因为只做镜像的。
利用mirror模块,业务可以将线上实时访问流量拷贝至其他环境,基于这些流量可以做版本发布前的预先验证,进行流量放大后的压测等等。(复制线上真实流量,在不影响真实业务前提下,利用复制流量来做故障分析、性能定位、迁移评估等功能。)
我是这样理解的,这里,mirror本意是镜子、镜像,这里可以理解就像一个镜像站点一样,将所有的请求都收集起来,这个镜像就代表了所有真实有效的原始请求。有了这个镜像,后续我们才可能用这个镜像去做一些事情,比如重现一下所有的请求,这就实现了把线上的流程复制到别的地方。
- nginx 1.13.4及后续版本内置ngx_http_mirror_module模块,提供流量镜像(复制)的功能。
- 支持流量放大,做法为:配置多份相同镜像。
- 相比tcp-copy的优势:无需录制流量,实时可用,配置相当简单。
- 源站请求,直接原路返回;正常配置下,mirror请求不影响源站请求及响应,源站nginx-server将流量复制到mirror站后,两者不再有任何交集。
配置流量复制
192.168.179.99流量镜像复制到上游服务192.168.179.100,配置如下:
192.168.179.99源站配置配置如下
[root@www ~]# echo "mirror.txt" > /usr/local/nginx/html/mirror.txt
server {
listen 80;
server_name localhost;
location / {
mirror /mirror;
mirror_request_body off;
}
location =/mirror{
proxy_pass http://192.168.179.100$request_uri;
#原始uri不会镜像,可以通过#$request_uri变量取得原始请求的uri
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
192.168.179.100镜像站配置
server{
listen 80;
server_name localhost;
charset utf-8;
error_page 404 =200 /404.html;
location /{
return 200 'mirror respone';
}
}
客户端192.168.179.102去请求192.168.179.99资源
[root@localhost ~]# curl 192.168.179.99/mirror.txt
mirror.txt
-----------------------------------------------------------------------------------------
192.168.179.99日志如下:
192.168.179.102 - - [29/Apr/2020:11:30:09 +0800] "GET /mirror.txt HTTP/1.1" 200 11 "-" "curl/7.29.0" "-" --通过日志可以看到99收到了该请求
192.168.179.100日志如下:
192.168.179.99 - - [29/Apr/2020:11:30:09 +0800] "GET /mirror.txt HTTP/1.0" 200 14 "-" "curl/7.29.0" "192.168.179.102" --上游服务也收到该请求,可以看到时间也是一样
可以看到上游服务和代理服务都拿到到了客户端相同的请求这样实现了流量的拷贝
流量放大配置方法(配置多分mirror)
server {
listen 80;
server_name web1.www.com;
# 源站配置
location / {
access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
mirror /mirror;
# 多加一份mirror,流量放大一倍
mirror /mirror;
mirror_request_body on;# Indicates whether the client request body is mirrored. default value is on.
proxy_pass http://web1.upstream.name;
}
# 镜像站点配置
location /mirror {
internal;
#internal 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
#跳转到下面的内部server
proxy_pass http://mirror.web1.upstream.name$request_uri;
proxy_pass_request_body on;
# Indicates whether the original request body is passed to the proxied server. default #value is on
proxy_set_header X-Original-URI $request_uri; # reset uri
}
}
mirror日志
镜像配置不正确,导致复制操作没正常执行,此时nginx可能缺少错误日志,严重影响调试,所以非常建议配置镜像日志。mirror中不支持配置access_log,解决方法:mirror-location跳转到server,在server中配置accesslog。
server {
listen 80;
server_name web1.www.com;
# 源站配置
location / {
access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
mirror /mirror;
mirror_request_body off;# Indicates whether the client request body is mirrored. default value is on.
proxy_pass http://web1.upstream.name;
}
# 镜像站点配置
location /mirror {
internal; # 内部配置
# 跳转到下面的内部server
proxy_pass http://127.0.0.1:10901$request_uri;
proxy_pass_request_body off; # Indicates whether the original request body is passed to the proxied server. default value is on
# Content-Length必须配置在mirror中否则无效
proxy_set_header Content-Length "";
# mirror_request_body/proxy_pass_request_body都设置为off,则Conten-length需要设置为"",否则有坑
proxy_set_header X-Original-URI $request_uri; # 使用真实的url重置url
}
}
server {
# server没法设置为内部
listen 127.0.0.1:10901;
location / {
# 判断放在server,使得post请求日志可以记录
if ($request_method != GET) {
return 403;
}
access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
proxy_pass http://mirror.web1.upstream.name;
}
}
相关文章
- centos7系统下安装php-fpm并配置nginx支持并开启网站gzip压缩
- FastDFS整合Nginx的模块:fastdfs-nginx-module报错:fdfs_define.h:15:27: 致命错误:common_define.h:没有那个文件或目录
- Deepin 15.4 编译安装 LNMP(PHP 5.6.31 + Nginx 1.12.1 + MySQL 5.6.36)
- nginx配置
- nginx安全: 配置http基本验证(Basic Auth)(nginx 1.18.0)
- OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能
- nginx的HTTP模块编写
- 大叔经验分享(77)openresty(nginx+lua)发http请求
- nginx重新整理——————http请求的11个阶段中的precontent阶段[十六]
- nginx重新整理——————http请求的11个阶段[十二]
- 利用nginx泛域名解析配置二级域名和多域名
- LNMP详解(十)——Nginx负载分担实战
- Nginx http_referer_module 防盗链原理和使用
- Nginx http_proxy_module模块实现缓存代理服务器
- 设置nginx开机启动
- Nginx第三方模块nginx_upstream_check_module实现http检测
- 已解决docker搜索收藏数最高的nginx镜像Python代码实现
- Nginx ACCESS日志过滤CSS JS 图片等静态文件——筑梦之路
- nginx无证书代理http/https协议两种解决方案——筑梦之路
- Nginx学习——http配置项解析编程
- consul集群搭建,配合nginx完成服务动态发现和健康检查
- Nginx之IP国家代码ngx_http_geoip2_module模块简介和使用
- Nginx之访问IP限制ngx_http_access_module模块简介和使用
- Nginx.conf 配置详解