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 复制请求

  1. server {
  2. listen 80;
  3. server_name web1.www.com;
  4. # 源站配置
  5. location / {
  6. access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
  7. mirror /mirror;
  8. mirror_request_body on;# Indicates whether the client request body is mirrored. default value is on.
  9. proxy_pass http://web1.upstream.name;
  10. }
  11. # 镜像站点配置
  12. location /mirror {
  13. internal; # 内部配置
  14. proxy_pass http://mirror.web1.upstream.name$request_uri;
  15. proxy_pass_request_body on; # Indicates whether the original request body is passed to the proxied server. default value is on
  16. proxy_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
  17. }
  18. }

3.2 不允许复制post请求

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

  1. server {
  2. listen 80;
  3. server_name web1.www.com;
  4. # 源站配置
  5. location / {
  6. access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
  7. mirror /mirror;
  8. mirror_request_body off;# Indicates whether the client request body is mirrored. default value is on.
  9. proxy_pass http://web1.upstream.name;
  10. }
  11. # 镜像站点配置
  12. location /mirror {
  13. # 判断请求方法,不是GET返回403
  14. if ($request_method != GET) {
  15. return 403;
  16. }
  17. internal; # 内部配置
  18. proxy_pass http://mirror.web1.upstream.name$request_uri;
  19. proxy_pass_request_body off; # Indicates whether the original request body is passed to the proxied server. default value is on
  20. proxy_set_header Content-Length ""; # mirror_request_body/proxy_pass_request_body都设置为off,则Conten-length需要设置为"",否则有坑
  21. proxy_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
  22. }
  23. }

3.3 流量放大

配置多分mirror

  1. server {
  2. listen 80;
  3. server_name web1.www.com;
  4. # 源站配置
  5. location / {
  6. access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
  7. mirror /mirror;
  8. # 多加一份mirror,流量放大一倍
  9. mirror /mirror;
  10. mirror_request_body on;# Indicates whether the client request body is mirrored. default value is on.
  11. proxy_pass http://web1.upstream.name;
  12. }
  13. # 镜像站点配置
  14. location /mirror {
  15. internal; # 内部配置
  16. proxy_pass http://mirror.web1.upstream.name$request_uri;
  17. proxy_pass_request_body on; # Indicates whether the original request body is passed to the proxied server. default value is on
  18. proxy_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
  19. }
  20. }

4. mirror日志

mirror中不支持配置access_log,解决方法:mirror-location跳转到server,在server中配置accesslog.

  1. server {
  2. listen 80;
  3. server_name web1.www.com;
  4. # 源站配置
  5. location / {
  6. access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
  7. mirror /mirror;
  8. mirror_request_body off;# Indicates whether the client request body is mirrored. default value is on.
  9. proxy_pass http://web1.upstream.name;
  10. }
  11. # 镜像站点配置
  12. location /mirror {
  13. internal; # 内部配置
  14. # 跳转到下面的内部server
  15. proxy_pass http://127.0.0.1:10901$request_uri;
  16. proxy_set_header X-Original-URI $request_uri; # 使用真实的uri重置uri
  17. }
  18. }
  19. server {
  20. # server没法设置为内部
  21. listen 127.0.0.1:10901;
  22. location / {
  23. access_log /data/nginx/1.14.1/logs/web1/access.log accesslog;
  24. proxy_pass http://mirror.web1.upstream.name;
  25. }
  26. }

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会报如下错误:

  1. "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
  2. at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:229)
  3. at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:150)
  4. at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128)
  5. at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
  6. at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158)
  7. at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
  8. at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
  9. at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
  10. at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
  11. 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. 手撕Vue-编译模板数据

    经上一篇编译指令数据后,我们已经可以将指令数据编译成具体需要展示的数据了,上一篇只是编译了指令数据,还没有编译模板数据,这一篇我们就来编译模板数据. 也就是 {{}} 这种模板的形式我们该如何编译,其 ...

  2. centos离线安装mongodb-database-tools

    mongodb-database-tools是MongoDB数据库工具的命令行的工具,用于工作与MongoDB部署.可以使用mongodump和mongoimport很方便的导入导出备份数据. 该数据 ...

  3. .net 工具箱不可用/怎样初始化vs环境 解决方案

    在开始菜单里面执行的.开始菜单->Microsoft Visual Studio 2005->Visual Studio Tools->Visual Studio 2005 命令提示 ...

  4. KB0004.如何进行DoraCloud版本升级?

    升级过程为: 1).现有版本,进入维护模式,导出系统数据.    2).记录现当前版本DoraCloud VM 的IP地址,子网掩码.网关.DNS信息,将VM关机. 3).安装新版本DoraCloud ...

  5. RSAToken 的签名算法 SHA256withRSA、数字签名

    数字签名的意义,看下百科:数字签名sign可不是对数据的加密和解密,而是生成签名和验证签名. https://baike.baidu.com/item/%E6%95%B0%E5%AD%97%E7%AD ...

  6. [JVM] Java内存分配

    Java内存分配 程序计数器 程序计数器是一块较小的内存区域,作用可以看做是当前线程执行的字节码的位置指示器.分支.循环.跳转.异常处理和线程恢复等基础功能都需要依赖这个计算器来完成. 虚拟机栈 虚拟 ...

  7. sanic和tornado的简单性能测试

    操作系统 : CentOS7.3.1611_x64 Python 版本 : 3.6.8 tornado版本:6.0.2 sanic版本:19.9.0 CPU : Intel(R) Core(TM) i ...

  8. SSD 简介—— NAND 芯片介绍

    制作 存储芯片的制作和其他芯片制作大致相同,从沙子中提取单晶硅制作晶圆再封装芯片. 闪存芯片从架构上分为NOR和NAND NOR Flash的source line把每个cell都并联起来,而NAND ...

  9. openai chatGPT 原理通俗介绍

    引言 近年来,随着深度学习技术的不断发展,自然语言处理(NLP)领域取得了长足的进步.ChatGPT(Generative Pre-trained Transformer)作为一种先进的语言生成模型, ...

  10. 【Lua】ToLua逻辑热更新

    1 前言 ​ Lua基础语法 中系统介绍了 Lua 的语法体系,xLua逻辑热更新 中介绍了 xLua 的应用,本文将进一步介绍 Unity3D 中基于 ToLua 实现逻辑热更新. ​ 逻辑热更新是 ...