利用NGINX内置模块mirror进行流量复制等操作
文章发布较早,内容可能过时,阅读注意甄别。
在日常工作中,会有这样的场景,为了便于测试,可能希望线上的请求能够同步到测试一部分,以便于验证某些功能,或者是在多套测试环境的情况下,希望能够将某些请求在几个环境同步,比如在 1 环境测试的时候生成了某个图片或者视频,这个生成依赖于一个请求的回调,而如果没有特别配置,则这个请求就只在当前环境中生效,这对测试工作有相当大的不便。
于是,我们需要引入流量复制这一概念,流量复制有不少工具可以实现,有 Gor、tcpreplay、tcpcopy 等,而今天将要使用的,是配置简单,使用方便的 NGINX 的一个模块:ngx_http_mirror_module
。
mirror: 中文为镜像的意思,这里指流量复制的目的地。
# 1,特性。
- nginx 1.13.4 及后续版本内置 ngx_http_mirror_module 模块,提供流量镜像 (复制) 的功能。
- 支持流量放大,做法为:配置多份相同镜像。
- 相比 tcp-copy 的优势:无需录制流量,实时可用;配置相当简单。
- 源站请求,直接原路返回;正常配置下,mirror 请求不影响源站请求及响应,源站 nginx-server 将流量复制到 mirror 站后,两者不再有任何交集。
mirror 模块在 Nginx 1.13.4 以后的版本中默认是启用的,只需看一下版本即可,不必重新编译。
# 2,简单配置。
先看下当前使用的 NGINX 版本:
$ nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module
1
2
3
4
5
6
2
3
4
5
6
接着添加如下配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8181;
access_log /var/log/nginx/test.log;
root html/test;
}
server {
listen 8282;
access_log /var/log/nginx/mir1.log;
root html/mir1;
}
server {
listen 8383;
access_log /var/log/nginx/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;
server_name localhost;
location / {
mirror /mirror1;
mirror /mirror2;
proxy_pass http://backend;
}
location = /mirror1 {
internal;
proxy_pass http://test_backend1$request_uri;
}
location = /mirror2 {
internal;
proxy_pass http://test_backend2$request_uri;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
说明:
location / { # location /指定了源uri为/,也可以定义为其他指定接口
mirror /mirror1; # mirror /mirror指定镜像uri为/mirror
mirror /mirror2; # 有多个需要复制流量的,可以配置多条
mirror /mirror2; # 配置多条情况下,将会起到流量放大的作用,即主配置请求一次,镜像端会有两次
# mirror_request_body on; # 指定是否镜像请求body部分,请求自动缓存;
proxy_pass http://backend; # 指定处理主流量的后端Server
}
location = /mirror1 {
internal; # 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
proxy_pass http://test_backend1$request_uri; # 指定将要复制流量的Server1
}
location = /mirror2 {
internal;
proxy_pass http://test_backend2$request_uri;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3,验证。
此时验证也非常简单,检测配置无误,然后启动 NGINX,使用 tail 同时监听三个日志,然后请求 127.0.0.1/index.html,会发现这一请求同时在日志中出现了。
创建一下访问内容:
$ cd /usr/local/nginx/html/
$ mkdir test mir1 mir2
$ echo test > test/index.html
$ echo mir1 > mir1/index.html
$ echo mir2 > mir2/index.html
$ curl 127.0.0.1/index.html
1
2
3
4
5
6
2
3
4
5
6
请求看效果:
参考:
- https://dwz.cn/T1rLisdA
- https://dwz.cn/8atYbyNk
- https://dwz.cn/UpMMbdiC
上次更新: 2024/07/04, 22:40:37