背景

Web 应用压力测试工具有很多,比如Apache ab, Apache JMeter等。但是这些工具都没能解决一个问题:如何正确模拟生产环境的流量。对于线下的传统压力测试,难以模拟真实流量,尤其难以模拟正常流量混杂着各色异常流量。

系统重构或重要变更上线前,可以复制线上真实流量,实时模拟线上流量,甚至可以放大真实流量,进行压力测试,以评估系统承载能力。反过来也可以这样,如果线上跑着发现有性能瓶颈,但线下环境难以复现,还不如把真实流量拷贝到线下重放,毕竟线下环境便于上各种排查手段,重放几遍都行,直到找到问题。

因此,需要研究如何复制线上真实流量并引流到测试环境。主要的工具有TCPCopy和GoReplay 。下面分别介绍这两个工具。

TCPCopy

TCPCopy 是一种请求复制(复制基于 TCP 的 packets)工具 ,通过复制在线数据包,修改 TCP/IP 头部信息,发送给测试服务器,达到欺骗测试服务器的TCP 程序的目的,从而为欺骗上层应用打下坚实基础。

TCPCopy由网易技术部的王斌在王波的工作基础上中2010年开发,并与2011年9月开源。Github地址,最新的发布版本号是 1.2.0。其应用领域较广,目前已经应用于国内各大互联网公司,很多公司的模拟在线测试都是基于 TCPCopy 做的。

总体说来,tcpcopy主要有如下功能:
1)分布式压力测试工具,利用在线数据,可以测试系统能够承受的压力大小(远比ab压力测试工具真实地多),也可以提前发现一些bug
2)普通上线测试,可以发现新系统是否稳定,提前发现上线过程中会出现的诸多问题,让开发者有信心上线
3)对比试验,同样请求,针对不同或不同版本程序,可以做性能对比等试验
4)利用多种手段,构造无限在线压力,满足中小网站压力测试要求
5)实战演习(架构师必备)

tcpcopy可以用于实时和离线回放领域,并且tcpcopy支持mysql协议的复制,开源二年以来,功能上越来越完善。

架构如下图所示:

线上服务器Online Server(OS):上面要部署 TCPCopy,从数据链路层(pcap 接口)抓请求数据包,发包是从IP层发出去;
测试服务器Test Server(TS):最新的架构调整把 intercept 的工作从 TS 中 offload 出来。TS 设置路由信息,把 被测应用 的需要被捕获的响应数据包信息路由到 AS;
辅助服务器Assistant Server(AS):这是一台独立的辅助服务器,原则上一定要用同网段的一台闲置服务器来充当辅助服务器。AS 在数据链路层截获到响应包,从中抽取出有用的信息,再返回给相应的 OS 上的 tcpcopy 进程。

TCPCopy实验

1. 实验环境

线上服务器 --> 192.168.119.158
测试服务器 --> 192.168.119.152
辅助服务器 --> 192.168.119.151

•tcpcopy运行在线上服务器上,tcpcopy会把线上服务器收到的流量,重放给测试服务器,重放的时候tcpcopy修改了IP数据包的源IP地址(譬如修改源地址为192.168.2.254)。所以,线上服务器和测试服务器应该部署相同的服务。
•tcpcopy把源IP伪造成192.168.2.254的包发给了测试服务器,如此,测试服务器在处理完tcpcopy发过来的数据以后,会把这些数据包返回给客户端,即伪造的192.168.2.254。
•由于没有192.168.2.254这个地址,我们在测试服务器添加一条专门的路由,把发往192.168.2.0/24的数据包,都全部转交给辅助服务器。
•为了保证辅助服务器会接受这些本不属于自己的,部署在辅助服务器上的intercept就发挥作用了。辅助服务器还可以用来把客户端的请求返回给tcpcopy,但是默认只返回响应头部给tcpcopy。辅助服务器应该类似于黑洞。

2. 线上机器安装tcpcopy

在线上服务器上下载,然后编译安装tcpcopy的包,如下:

wget https://github.com/session-replay-tools/tcpcopy/archive/v1.2.0.tar.gz
tar xzvf v1.2.0.tar.gz
cd tcpcopy-1.2.0
./configure
make
make install

3. 辅助机器安装intercept

yum -y install libpcap-devel
wget https://github.com/session-replay-tools/intercept/archive/1.0.0.tar.gz
tar xvf 1.0.0.tar.gz
cd intercept-1.0.0
./configure
make
make install

4. 部署

简单的在线上服务器和测试服务器上启动一个简单的springboot程序,提供一个http接口,打印并返回hello world。

@RequestMapping("/hello")
private String service()  {LOG.info("hello world");return "hello world";
}

先在辅助服务器上开启intercept,没有intercept的话,tcpcopy启动不起来:

#/usr/local/intercept/sbin/intercept -i ens33 -F tcp and src port 80 -d

•-i,intercept会监听端口,和tcpcopy进行通信,-i就是指定监听在哪个端口。tcpcopy启动的时候会来连这个端口,如果连不上,就会启动失败。
•-F, 过滤规则,语法和pcap一样。
•-d, 已守护进程方式运行
还有其它参数可以使用,-h便可以查看,不详细解释了。

辅助机的 intercept 通过-F 参数制定捕获规则,捕获tcp连接中源端口为80的所有数据,也即是测试机的回应数据。其作用是将测试机路由过来的响应数据捕获下来,完成整个请求回应的流程且保证测试机产生的回应数据不会流向线上环境。
intercept 会监听 tcp 36524 端口,并和线上服务器的 tcpcopy 之间建立通信,我们通过ss命令可以观察到。

然后,在线上服务器开启tcpcopy:

# /usr/local/tcpcopy/sbin/tcpcopy -x 80-192.168.119.152:80 -s 192.168.119.151 -c 192.168.2.254 -n 2 -d

•-x, 是指本机80端口的流量copy到测试服务器192.168.119.152的80端口
•-s, 指定intercept机器的地址,tcpcopy要和intercept建立连接
•-c 伪装地址,在把流量复制到测试服务器的时候,修改数据包的源地址为192.168.2.254,这样方便指定路由。也可以写成192.168.2.x,这样源地址就是指定网段中的地址了。
•-n 流量放大倍数,如果不是压测目的就不用指定这个参数。
-d 以守护模式运行。

最后,在测试服务器上开启路由(切记辅助服务器要和测试服务器在一个子网里):

# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.119.151

路由的意思是把发往192.168.2.0/24地址的数据包全部转给辅助服务器。这样在辅助机上就可以对全部的回应包进行截获处理了。

5. 测试效果

在另外一台机器上,通过Jmeter向线上服务器连续发起5次请求http://192.168.119.1/hello

然后查看两个HTTP服务器的实时日志,
线上服务器的结果:

测试服务器的结果:

可以看到,正如tcpcopy命令中设置的n=2,在测试服务器上,请求变成了10次,明显看到流量被放大了2倍。效果正如预期。

通过tcpdump抓包查看:

tcpdump -n -i ens33 port 80 -w tcpcopy.cap

可以看到,除此之外,到在线服务器和到测试服务器的请求ip是不一样的。前者是192.168.119.1,而后者是转换后的192.168.2.254,也就是我们捏造的IP,注意伪造IP的时候,一定要避免环境中存在的IP和常用的IP。

注意
•辅助服务器要扮演成一个黑洞,所以不能开启ip_forward
•在请求会修改数据的地方,譬如修改数据库,如果配置不当,可能导致数据被重复修改多次。

6. 离线模式

需要在安装tcpcopy的时候,configure时加上–offline参数才能支持离线回放。除此之外,其他配置和在线模式一样。

cd tcpcopy-1.2.0
./configure --offline
make
make install

使用tcpdump来抓包录制pcap离线文件

tcpdump -i ens33 -w online.pcap tcp and port 80

tcpcopy命令执行增加-i指定文件名

# /usr/local/tcpcopy/sbin/tcpcopy -x 80-192.168.119.152:80 -s 192.168.119.151 -c 192.168.2.254 -n 2 -d  -i ./online.pcap

可以观察到和在线模式同样的测试结果

GoReplay

GoReplay,原名叫gor,是一款go语言实现的简单安全的HTTP 实时流量复制的开源工具,用于捕获和回放实时HTTP流量到测试环境中,以便不断地用真实数据测试应用系统,可以用于增强对代码部署、配置更改和基础设施更改的信心。完美解决了 HTTP 层实时流量复制和压力测试的问题。
官方网站,github地址,最新的版本为v0.16.1。

架构如下图所示:

从架构图可以看到,只需要http入口服务器上执行一个进程,就可以把生产环境的流量复制到任何地方,比如 Staging 环境、Dev 环境。

通过查看官网可以看到,开源版本的GoReplay只支持http,如果需要支持Thrift、protoBuffers等协议,需要购买GoReplay pro版本。

GoReplay 的功能
GoReplay支持流量的放大和缩小、频率限制,这样不需要搭建和生产环境一致的服务器集群也可以正确测试。GoReplay 还支持根据正则表达式过滤流量,这意味着可以单独测试某个 API 服务。还可以修改 HTTP 请求头,比如替换 User-Agent, 或者增加某些 HTTP Header 。

GoReplay还可以把请求记录到文件,以备回放和分析。GoReplay 支持和 ElasticSearch 集成,将流量存入 ES 进行实时分析。

GoReplay 的使用

  1. 输入参数
    –input-raw 捕获 HTTP 流量,需指定端口号
    –input-file 使用 --output-file 记录的文件作为输入
    –input-tcp 将多个 Gor 实例获取的流量聚集到一个 Gor 实例
  2. 输出参数
    –output-http 相应流量的终端,接收 URL 地址
    –output-file 将获取的流量记录如文件
    –output-tcp 将获取的流量转移至另外的 Gor 实例,与 --input-tcp 组合使用
    –output-stdout debug 工具,将流量信息直接输出
  3. 流量限制
    使用线上流量测试时,如线上流量过大,如果将全部流量导入演示(staging)或者 测试(dev)服务器,后果可想而知,GoReplay 流量限制策略为随机丢弃一部分请求,根据 Header 或者 URL 参数丢弃一部分请求,随机丢弃一部分请求,Absolute 如果当前秒请求达到限制,忽略剩余请求,直至下一秒计数器恢复Percentage 对于输入文件设定该参数将加速或者减缓请求执行速度。根据设定百分比使用随机数生成器决定请求是否被接受
    命令 Absolute 每秒最大 10 个请求数
    sudo ./goreplay --input-raw :8888 --output-http “http://t1:8888|10”
    命令 Percentage 获取少于 10% 的流量
    sudo ./goreplay --input-raw :8888 --output-http “http://t1:8888|10%”
    根据 Header 或者 URL 参数丢弃一部分请求
    命令 Limit based on header value
    sudo ./goreplay --input-raw :8888 --output-tcp “replay.local:28020|10%”
    –http-header-limiter “X-API-KEY: 10%”
  4. 请求过滤
    –http-allow-url 允许正则 URL,不包换主句名部分
    –http-disallow-url 不允许正则 URL
    –http-allow-header 允许的 Header 头
    –http-disallow-header 不允许的 Header 头
    –http-allow-method 允许的请求方法
  5. 命令举例
    简单的 HTTP 流量复制:
    goreplay -input-raw :80 -output-http “http://staging.com”
    HTTP 流量复制频率控制:
    goreplay -input-tcp :28020 –output-http “http://staging.com|10″
    HTTP 流量复制缩小:
    goreplay -input-raw :80 -output-tcp “replay.local:28020|10%”
    HTTP 流量记录到本地文件:
    goreplay -input-raw :80 -output-file requests.gor
    HTTP 流量回放和压测:
    goreplay -input-file “requests.gor|200%” -output-http “staging.com”
    HTTP 流量过滤复制:
    goreplay -input-raw :8080 -output-http staging.com -output-http-url-regexp ^www.

GoReplay实验

1. 实验环境

线上服务器 --> 192.168.119.158
测试服务器 --> 192.168.119.152

2. 安装部署

在线上服务器上安装:

wget https://github.com/buger/goreplay/releases/download/v0.16.1/gor_0.16.1_x64.tar.gz
tar xzf gor_0.16.1_x64.tar.gz

解压后即为一个名叫goreplay的二进制可执行文件。

在两个服务器上启动一个简单的springboot程序,提供一个http接口,打印并返回hello world。

@RequestMapping("/hello")
private String service()  {LOG.info("hello world");return "hello world";
}
离线模式

在158上执行如下命令

./goreplay -input-raw :80 -output-file requests.gor

同样也在另外一台机器上,向线上服务器发起5次请求

这时候查看生成的requests.gor文件:

可以看到,生成的 requests_0.gor文件即为5个http请求报文。

当中线上服务器执行命令时

./goreplay -input-file=requests_0.gor -output-http="http://192.168.119.152:80"

可以看到这152服务器上的应用可以接受到请求。

在线模式

在158上执行如下命令

   ./goreplay  -input-raw :80  -output-http="http://192.168.119.152:80"

这时发送请求 curl http://192.168.119.1:80/hello
可以看到158和152上同时都收到的请求

流量复制导流工具研究相关推荐

  1. HTTP流量复制引流工具(web压测及线上问题复现利器)--Gor(GoReplay)

    一.有什么用 将机器http请求复制转发到指定的机器上去. 通常可能会通过ab等压测工具来对单一http接口进行压测.但如果是需要http服务整体压测,使用ab来压测工作量大且不方便,通过线上流量复制 ...

  2. TCPCopy 线上流量复制工具

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

  3. php 压测流量回放,Web流量复制和压力测试工具Gor

    Gor概述 Gor 是用 Golang 写的一个 HTTP 实时流量复制工具.只需要在 LB 或者 Varnish 入口服务器上执行一个进程,就可以把生产环境的流量复制到任何地方,比如 Staging ...

  4. 流量复制工具gor使用简介

    gor安装部署: 环境分配: 192.168.199.185 模拟线上环境 192.168.199.186模拟测试环境 192.168.199.187流量复制辅助服务器 现在要做的是把到192.168 ...

  5. TcpCopy 流量复制

    1 概述 tcpcopy是一种请求复制(所有基于tcp的packets)工具,可以把在线流量导入到测试系统中去(也可以在测试系统内部放大流量),从而模拟真实运行环境,以便排查测试系统的性能问题和风险. ...

  6. 基于Gor实现流量复制(加middleware功能增强)

    最近做功能重构,在上线前要求验证重构后的代码与老代码实现逻辑是否一致,基于这个需求,需要在生产环境做一个功能将生产服务器上的流量复制一份发送到测试服务器上. 就这个事情这几天考察了三种技术,1. 基于 ...

  7. 流量复制_详解Linux系统流量复制--gor、tcpcopy、nginx模块流量复制等

    概述 对于一些有并发要求的业务,特别是对接外部流量时,产品上线前一定要做的就是压力测试,但是常规的压力测试并不能覆盖所有情况.以gemeter.ab,.webbench.http_load为例,这些通 ...

  8. 指定module_详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

    概述 因为我们的接口环境是在winserver上,而gor又刚好没对应版本(网上很多办法都试过了...哪位朋友测试过可以的话指点下),所以用了nginx的ngx_http_mirror_module模 ...

  9. game module 停止运行_详解流量复制解决方案--NGINX的ngx_http_mirror_module模块实现

    概述 因为我们的接口环境是在winserver上,而gor又刚好没对应版本(网上很多办法都试过了...哪位朋友测试过可以的话指点下),所以用了nginx的ngx_http_mirror_module模 ...

最新文章

  1. Android:dagger2让你爱不释手-基础依赖注入框架篇
  2. Caffe学习系列(14):初识数据可视化
  3. 七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理
  4. 【信号】信号集、sigprocmask、sigpending
  5. python识别颜色1007python识别颜色_python读取word文档识别字段颜色,解析字段
  6. Maven仓库—Nexus环境搭建及使用
  7. 元素内容必须由格式正确的字符数据或标记组成_字符编码是什么?html5如何设置字符编码?...
  8. python爬取豆瓣书籍_Python爬取豆瓣读书
  9. 项目中用到的ws2811炫彩灯控制程序
  10. 使用apt更新和升级系统软件
  11. C#实现按键精灵的'找图' '找色' '找字'的功能
  12. (79)【按键】[独立按键] - 1: 单击,双击,三击以及N击
  13. 安装docker遇到的坑
  14. windows10启动项修复||an operating system wasn't found解决办法
  15. 治疗贫血的几款食疗方
  16. 场论:关于矢量场梯度=0的证明
  17. .net 2.0 下的FTP搜索引擎实现
  18. 自学考试-“运筹学基础”
  19. 阳关林场的前世今生:结合锁眼卫星(Keyhole[KH])发掘“阳关林场”55年来的变化
  20. VUE探索第二篇-手脚架(vue-cli)

热门文章

  1. 华为智慧屏鸿蒙系统缺点,华为智慧屏用户评论及华为智慧屏电视真实体验优缺点情况...
  2. Code Review Checklist
  3. 力天创见客流工程实施
  4. 信捷PLC程序 八轴程序,有伺服也有步进,内部有伺服和步进计算公式换算
  5. 如何来投放广告更赚钱
  6. ppt文字提取转word
  7. python做测试小工具_自制快速冒烟测试小工具--基于python多线程(2)
  8. 4.5 函数最佳逼近
  9. 优思学院|德国制造为何被受推崇?
  10. Oracle数据库常见问题处理