我们在测试接口的时候。为了便于测试,可能希望线上的请求能够同步到测试一部分,以便于验证某些功能,或者是在多套测试环境的情况下,希望能够将某些请求在几个环境同步,比如在1环境测试的时候生成了某个图片或者视频,这个生成依赖于一个请求的回调,而如果没有特别配置,则这个请求就只在当前环境中生效,这对测试工作有相当大的不便。于是,我们需要引入流量复制这一概念。
将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如:
可以验证功能是否正常,以及服务的性能;
用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问;
这跟灰度发布还不太一样,镜像流量不会影响真实流量;
可以用来排查线上问题;
重构,假如服务做了重构,这也是一种测试方式;
在正常的流量复制的时候呢,我们用很多工具可以使用。Gor、tcpreplay、tcpcopy 等。我们这次分析的是利用nginx的内置模块来完成。
nginx 1.13.4及后续版本内置ngx_http_mirror_module模块,提供流量镜像(复制)的功能。
安装nginx
brew install nginx
安装后,我们看下nginx版本。
那么我们看看如何实现流量复制,如何配置呢。我们看下对应模块对应的配置
location / { # location /指定了源uri为/,也可以定义为其他指定接口
mirror /mirrorone; # mirror /mirror指定镜像uri为/mirror
mirror /mirrortwo; # 有多个需要复制流量的,可以配置多条
mirror /mirrortwo; # 配置多条情况下,将会起到流量放大的作用,即主配置请求一次,镜像端会有两次
# mirror_request_body on; # 指定是否镜像请求body部分,请求自动缓存;
proxy_pass http://backend; # 指定处理主流量的后端Server
}
location = /mirrorone {
internal; # 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
proxy_pass http://test_backend1$request_uri; # 指定将要复制流量的Server1
}
location = /mirrortwo {
internal;
proxy_pass http://test_backend2$request_uri;
}
那么我们如何实现一个nginx的配置呢。下面展示下我的配置
worker_processes 1;
events {
worker_connections 1024;
}
http {
default_type application/octet-stream;
sendfile on;
server {
listen 8181;
root html/test;
}
server {
listen 8282;
access_log /usr/local/Cellar/nginx/1.19.0/logs/mir1.log;
root html/mir1;
}
server {
listen 8383;
access_log /usr/local/Cellar/nginx/1.19.0/logs/mir2.log;
root html/mir2;
}
upstream backend {
server 127.0.0.1:8181;
}
upstream test_backend1 {
server 127.0.0.1:8282;
}
upstream test_backend2 {
server 127.0.0.1:8383;
}
server {
listen 80;
index index.php index.html;
server_name localhost;
location / {
mirror /mirrorone;
mirror /mirrortwo;
proxy_pass http://backend;
}
location = /mirrorone {
internal;
proxy_pass http://test_backend1$request_uri;
}
location = /mirrortwo {
internal;
proxy_pass http://test_backend2$request_uri;
}
}
}
需要在nginx目录下面创建三个目录
在目录下面的创建index.html,然后内容一个test
test
我们去启动下nginx的对应服务,
sudo nginx -c /Users/leizi/Desktop/new.conf
然后我们去请求
curl 127.0.0.1/index.html
我们看下请求的返回
我们去看下对应的两个复制到的服务的日志
这样就简单的实现了使用nginx进行流量复制。