本篇文章介绍了七层流量复制的一种方法,通过引入ngx_http_mirror_module模块实现流量复制的效果。
回顾上篇文章:结合 nginx waf 分享 nginx 防刷技巧
压力测试重要性与压测工具
在业务系统开发的流程里,压力测试是很重要的一个环节,通过压测可以掌握服务程序的响应时间、并发数、吞吐量等,从而可预估系统的服务质量、可承载用户和需要的硬件资源,以及定位系统瓶颈等。
在 WEB 应用测试中,常用的流量产生工具大体可以分为两种:
1 模拟请求工具,以 ab, webbench、http_load 等为例 ,这些工具小巧简单,上手学习较快;但不足以还原真实场景,同时它们的请求模式也过于单一和理想化;
2 流量复制,以 Gor、tcpreplay、tcpcopy 等,这些工具复制的流量贴近真实场景,支持流量的放大和缩小,但是实现也就相对复杂一些。
而我们经常使用的 Nginx, 它其实也是一个很棒的流量复制工具,那就是模块 ngx_http_mirror_module,是在 Nginx 1.13.4 中引入,它是一种应用层的流量复制工具, 与其他工具相比它有以下几点优点:
1 可以将线上流量拷贝到测试环境,实时的模拟线上环境;
2 该模块内置于 nginx 中,不需要经过复杂的配置就能实现 ,目前只实现了两个配置指令,用法相当简单;
3 支持流量放大,对线上影响较小。
指令说明
Directives| Syntax: | mirror uri | off; |
| Default: |
mirror off; |
|
Context: |
http, server, location |
设置将镜像原始请求的 URI。 几个镜子可以在同一层上指定。
| Syntax: | mirror_request_body on | off; |
| Default: |
mirror_request_body on; |
| Context: | http, server, location |
指定是否镜像请求 body 部分,此选项与 proxy_request_buffering、fastcgi_request_buffering、scgi_request_buffering 和 uwsgi_request_buffering 冲突,一旦开启 mirror_request_body 为 on,则请求自动缓存。
使用演示
配置如下server {
listen 8080;
access_log /home/work/log/nginx/org.log;
root html/org;
}
server {
listen 8081;
access_log /home/work/log/nginx/mir.log ;
root html/mir;
}
upstream backend {
server 127.0.0.1:8080;
}
upstream test_backend {
server 127.0.0.1:8081;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
mirror /mirror;
proxy_pass http://backend;
}
location /mirror {
internal;
proxy_pass http://test_backend$request_uri;
}
}
配置说明
如上配置
端口 8080 服务可代表 生产环境, 端口号 8081 代表测试环境。
端口 80 代表生产中的 L7 层。

为了方便看到效果, 我们在两个目录中创建一个 index.html 文件,内容分别为 org 和 mir
echo org > org/index.html
echo mir > mir/index.html
验证curl http://127.0.0.1/index.htmlorg
可以看到在客户端看来,它得到了 org 的响应内容,说明是我们图中生产环境中响应
再来看下服务器上的日志:

可见 生产环境和 测试环境分别 收到一个 请求。
流量放大添加配置如下:

curl http://127.0.0.1/index.htmlorg
客户端来看,仍然是正常接收到一个响应;但是对于压测环境中 却已经变成了两个请求,实现了流量放大效果。

小米运维
和我们一起成为更酷的运维工程师