详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

Nginx/Web服务器
641
0
0
2022-03-27
标签   Nginx代理

概述

因为我们的接口环境是在winserver上,而gor又刚好没对应版本(网上很多办法都试过了...哪位朋友测试过可以的话指点下),所以用了nginx的ngx_http_mirror_module模块来实现需求。

01. ngx_http_mirror_module模块

nginx官网公布了nginx1.13.4最新的ngx_http_mirror_module模块,利用mirror模块,业务可以将线上实时访问流量拷贝至其他环境,基于这些流量可以做版本发布前的预先验证,进行流量放大后的压测等等。

02. mirror模块配置

mirror模块配置分为两部分,源地址和镜像地址配置,配置位置可以为nginx配置文件的http, server, location上下文,配置示例为:

mirror模块配置说明
#original
location / {       #location /指定了源uri为/
  root html;
  index index.html index.htm;
  mirror /mirror;       #lmirror /mirror指定镜像uri为/mirror
 mirror /mirror;       #lmirror /mirror指定镜像uri为/mirror
  mirror_request_body on;   # 指定是否镜像请求body部分,请求自动缓存;
}
#mirror
location /mirror {
  internal;internal  #指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
  proxy_set_header X-Original-URI $request_uri;
  proxy_set_header Host baidu-nginx-b.com; #proxy_set_header 设置镜像流量的头部
  proxy_pass http://192.168.1.100$request_uri; #proxy_pass 指定将镜像数据发送给test server的地址
}
location /mirror2 {
  internal;internal  #指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
  proxy_set_header X-Original-URI $request_uri;
  proxy_set_header Host baidu-nginx-b.com; #proxy_set_header 设置镜像流量的头部
  proxy_pass http://192.168.1.100$request_uri; #proxy_pass 指定将镜像数据发送给test server的地址
}

1、original配置

  • location /指定了源uri为/
  • mirror /mirror指定镜像uri为/mirror
  • mirror_request_body off | on 指定是否镜像请求body部分,此选项与proxy_request_buffering、fastcgi_request_buffering、scgi_request_buffering和 uwsgi_request_buffering冲突,一旦开启mirror_request_body为on,则请求自动缓存;
  • proxy_pass 指定上游server的地址

2、mirror配置

  • internal 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
  • proxy_pass 指定上游server的地址
  • proxy_set_header 设置镜像流量的头部

03. 流量复制--实验测试

1、下载nginx,解压缩,运行cmd,使用命令进行操作,不要直接双击nginx.exe,不要直接双击nginx.exe,不要直接双击nginx.exe

一定要在dos窗口启动,不要直接双击nginx.exe,这样会导致修改配置后重启、停止nginx无效,需要手动关闭任务管理器内的所有nginx进程,再启动才可以。

2、启动nginx服务,启动时会一闪而过是正常的

start nginx

3、查看任务进程是否存在,dos或打开任务管理器都行

tasklist /fi "imagename eq nginx.exe"

详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

4、如果程序没启动就直接start nginx启动,如果已经启动了就使用以下命令重新加载配置文件并重启

nginx -s reload

之后就打开浏览器访问刚才的域名及端口http://localhost:80,出现欢迎页就说明部署成功了

详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

5、启动web服务

这里偷个懒,用之前gor的一些半成品模拟两个server

d:\goreplay
gor file-server :8000
gor file-server :8001

6、配置NGINX

 upstream zs {
    server 127.0.0.1:8000;
}
upstream cs {
    server 127.0.0.1:8001;
}
server {
    listen 80;
    server_name localhost;
    #charset koi8-r;#access_log logs/host.access.log main;
    location /{
        #access_log D:\nginx\access.log accesslog;
        mirror /mirror;
        mirror_request_body on;
        proxy_pass http://zs;
    }
    # 镜像站点配置
    location /mirror {
        internal; # 内部配置
        proxy_pass http://cs$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;
    }
}

7、访问地址:

http://localhost/goreplay-1.0.0/

详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

可以看到两边都有对应的请求。


这个办法也是一个解决方案,对线上压力也比较小,不过用户访问生产服务器请求被nginx复制发送给测试服务器时,mirror不会输出http返回内容,这里就需要另外配置了。

另外一点就是不会保存流量下来,无法做到随时随地重放,只能说折中吧,还得继续研究。

后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~

详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现