1. 需求

功能需求

在不影响真实业务前提下,支持:

  1. 流量复制,用于线故障分析、系统迁移评估等
  2. 流量放大,通过多倍复制,实现放大流量,用于性能压测

配置需求

  1. 支持或禁止post请求复制
  2. 记录镜像请求的访问日志

2. 解决方案

nginx 1.13.4版本,内置ngx_http_mirror_module模块,能满足上述需求

ngx_http_mirror_module模块特性

  1. 相比tcp-copy的优势:无需录制流量,实时可用,配置相当简单
  2. 源站请求,直接原路返回
  3. 复制请求不影响源站请求,源站nginx-server将流量复制到mirror站后,两者不再有任何交集

3. 配置

下面配置在nginx 1.14.1验证通过,具体配置说明,请看注释信息

3.1 复制请求

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 on;# Indicates whether the client request body is mirrored. default value is on.
proxy_pass http://web1.upstream.name;
}
# 镜像站点配置
location /mirror {
internal; # 内部配置
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; # 使用真实的uri重置uri
}
}

3.2 不允许复制post请求

默认支持post请求,禁止需要将mirror_request_body修改为off,并判断$request_method

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 {
# 判断请求方法,不是GET返回403
if ($request_method != GET) {
return 403;
}
internal; # 内部配置
proxy_pass http://mirror.web1.upstream.name$request_uri;
proxy_pass_request_body off; # Indicates whether the original request body is passed to the proxied server. default value is on
proxy_set_header Content-Length ""; # mirror_request_body/proxy_pass_request_body都设置为off,则Conten-length需要设置为"",否则有坑
proxy_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
}
}

3.3 流量放大

配置多分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; # 内部配置
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; # 使用真实的uri重置uri
}
}

4. mirror日志

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_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
}
} server {
# server没法设置为内部
listen 127.0.0.1:10901;
location / {
access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
proxy_pass http://mirror.web1.upstream.name;
}
}

5. 性能评估

  • 测试前提:使用jemeter,在相同环境,使用30个并发,各请求3000次get或post方法,参数一样,一组为有mirror配置,另一组为没mirror配置。
  • 测试结果:mirror性能损失在5%以内,具体如下:

9. 遇到的问题

9.1 镜像配置不正确时,无日志

镜像配置不正确,导致复制操作没正常执行,但是nginx没有响应的错误日志,严重影响调试。非常建议配置镜像日志,配置方法如4. mirror日志

9.2 mirror_request_body/proxy_pass_request_body与Content-Length需配置一致

如果mirror_request_body或者proxy_pass_request_body设置为off,则Content-Length必须设置为"",因为nginx/tomcat处理post请求时,会根据Content-Length获取request_body。如果Content-Length不为空,但是把mirror_request_body、proxy_pass_request_body设置为off,nginx/tomcat以为post有内容,但是实际上request_body没有,nginx会报upstream请求超时,tomcat会报如下错误:

"2018-11-08T17:26:36.803+08:00" "331632b86ec64b829672066a96fc6324"      "department"        "group"   "project_name"        "hostname"    "127.0.0.1"     ""      "/post" "p=11"  "-"     "PostmanRuntime/7.1.1"  "ERROR" "xxx.GlobalControllerAdvice"       "operateExp"    "-"     "26"    "xxxx.GlobalControllerAdvice"       "unknown"       "org.springframework.http.converter.HttpMessageNotReadableException"    "I/O error while reading input message; nested exception is java.net.SocketTimeoutException"    "GlobalControllerAdvice中捕获全局异常"  "org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.net.SocketTimeoutException
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:229)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:150)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)

98. 引文

nginx流量复制与放大的更多相关文章

  1. Nginx流量复制

    1. 需求 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: 可以验证功能是否正常,以及服务的性能: 用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问: 这跟灰度发布还 ...

  2. 高并发 Nginx+Lua OpenResty系列(11)——流量复制/AB测试/协程

    流量复制 在实际开发中经常涉及到项目的升级,而该升级不能简单的上线就完事了,需要验证该升级是否兼容老的上线,因此可能需要并行运行两个项目一段时间进行数据比对和校验,待没问题后再进行上线.这其实就需要进 ...

  3. gor实现线上HTTP流量复制压测引流

    一.使用背景 gor 是一款go语言实现的简单的http流量复制工具,它的主要目的是使你的生产环境HTTP真实流量在测试环境和预发布环境重现.只需要在 代理例如nginx入口服务器上执行一个进程,就可 ...

  4. Nginx流量拷贝

    1. 需求 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: 可以验证功能是否正常,以及服务的性能: 用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问: 这跟灰度发布还 ...

  5. Nginx 流量和连接数限制

    1.Nginx流量限制 实现流量限制由两个指令 limit_rate 和 limit_rate_after 共同完成: limit_rate 语法:limit_rate rate; 默认值:limit ...

  6. Nginx 流量带宽等请求状态统计( ngx_req_status)

    Nginx 流量带宽等请求状态统计 ( ngx_req_status)  插件下载地址: wget http://nginx.org/download/nginx-1.4.2.tar.gz git c ...

  7. TCPCopy 线上流量复制工具

    TCPCopy是一种重放TCP流的工具,使用真实环境来测试互联网服务器上的应用程序. 一.描述: 虽然真实的实时流量对于Internet服务器应用程序的测试很重要,但是由于生产环境中的情况很负责,测试 ...

  8. 使用traefik进行流量复制

    文章转载自:https://mp.weixin.qq.com/s/nMMN7hAJK6SFn1V1YyxvHA Traefik 2.0 还引入了镜像服务,一种可以将流入流量复制并同时将其发送给其他服务 ...

  9. nginx mirror/post_action+gor实现https流量复制

    关于gor: 参考: https://www.cnblogs.com/jinjiangongzuoshi/p/11773070.html https://github.com/buger/gorepl ...

  10. Prometheus 监控 Nginx 流量 (三)

    介绍 基于Openresty和Prometheus.Consul.Grafana设计的,实现了针对域名和Endpoint级别的流量统计,使用Consul做服务发现.KV存储,Grafana做性能图展示 ...

随机推荐

  1. DES加密和base64加密

    DES简介:参考知乎 https://www.zhihu.com/question/36767829 和博客https://www.cnblogs.com/idreamo/p/9333753.html ...

  2. TienChin 渠道管理-删除渠道

    更改一下菜单权限,将删除渠道的 delete 改为 remove: ChannelController.java @PreAuthorize("hasPermission('tienchin ...

  3. 金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测股票价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)

    金融时间序列预测方法合集:CNN.LSTM.随机森林.ARMA预测股票价格(适用于时序问题).相似度计算.各类评判指标绘图(数学建模科研适用) 1.使用CNN模型预测未来一天的股价涨跌-CNN(卷积神 ...

  4. python3 牛客网:OJ在线编程常见输入输出练习(ACM模式)

    牛客网: 校招笔试真题_C++工程师.golang工程师_牛客网 其他语言输入输出见链接 1.输入两个数,输入数据包括多组. while True: try: a = list(map(int,inp ...

  5. windows共享文件创建----局域网办公

    一.共享文件设置 1.选择要共享的文件夹-----右键点击属性--------在上方选项栏选择共享----然后点击"高级共享" 2.勾选"共享此文件夹"---- ...

  6. WebAssembly入门笔记[4]:利用Global传递全局变量

    利用WebAssembly的导入导出功能可以灵活地实现宿主JavaScript程序与加载的单个wasm模块之间的交互,那么如何在宿主程序与多个wasm之间传递和共享数据呢?这就需要使用到Global这 ...

  7. React框架运行机制

    React框架运行主流程 1.JSX是JS语言的扩展,被babel编译后,会转换成React.creatElement(),这个方法返回的是一个虚拟DOM. 2.将虚拟DOM渲染到真实DOM的方法是R ...

  8. 教你用JavaScript随机生成密码

    案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript编程实战案例,做一个随机密码生成器.用户点击生成,输入框内就会生成一个由数字.大小写字母.特殊符号随机组 ...

  9. Java并发(十)----线程之守护线程

    默认情况下,Java 进程需要等待所有线程都运行结束,才会结束.有一种特殊的线程叫做守护线程,只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束. 例: log.debug(&q ...

  10. 5 款轻松上手的开源项目「GitHub 热点速览」

    大家都忙一年了,所以今天来点轻松的吧!就是那种拿来直接用.免费看的开源项目. 开源真是一个充满惊喜的宝库,很多开源软件比收费软件还好用,比如这款开箱即用的电视直播软件:my-tv,它免费.无广告.启动 ...