9.流量回放
流量回放的目的:通过对线上真实流量(例如http请求)捕获、存储、重放等操作,实现非生产环境中对用户行为的模拟。
适用场景:1、回归测试(例如OceanBase数据提供的OMA迁移评估工具);2、性能测试包括全链路压测(通过流速实现);3、问题复现。
关键技术:
- 流量录制:
- 网络层实现方案:使用goReplay、tcpDump(回放使用TCPCopy)等工具实现原始数据包的抓取。
- 应用层实现方案:通过AOP或者Java Agent技术实现对请求信息的获取。
- 流量存储:通常为本地存储,这里可以使用脚步同步数据进行汇聚。
- 流量回放:动态参数替换(例如token、时间戳等信息);并发控制(提供流速控制);协议转换(可能存储多种协议,需要进行转换)
难点:
- 动态参数替换:1、通过正则表达式替换固定数据;2、直接覆盖原始数据,例如压测时直接生成新的token
- https请求处理:
- 通常使用中间人捕获流量,例如nginx获得卸载证书后的请求,再配合日志实现请求捕获。
- 基于Linux内核探针技术实现,例如eBPF,基于内核态探针捕获 SSL/TLS 握手密钥,无需 CA 证书即可解析 HTTPS 明文
- 数据隔离性:1、创建影子库(数据量和表结构都与生产环境一致); 2、通过Java Agent技术实现Dao层的接口的mock。
1.jvm-sandbox-repeater
jvm-sandbox-repeater是JVM-Sandbox生态体系下的重要模块,它具备了JVM-Sandbox的所有特点,插件式设计便于快速适配各种中间件,封装请求录制/回放基础协议,也提供了通用可扩展的各种丰富API。
源码地址:https://github.com/alibaba/jvm-sandbox-repeater
通用流量录制回放工具 jvm-sandbox-repeater 尝鲜–系列文章
repeater的核心能力是什么?
- 通用录制/回放能力
- 无侵入式录制HTTP/Java/Dubbo入参/返回值录制能力(业务系统无感知)
- 基于TTL提供多线程子调用追踪,完整追踪一次请求的调用路径
- 入口请求(HTTP/Dubbo/Java)流量回放、子调用(Java/Dubbo)返回值Mock能力
- 快速可扩展API实现
- 录制/回放插件式架构
- 提供标准接口,可通过配置/简单编码实现一类通用插件
- standalone工作模式
- 无需依赖任何服务端/存储,可以单机工作,提供录制/回放能力
repeater的可以应用到哪些场景?
- 业务快速回归
- 基于线上流量的录制/回放,无需人肉准备自动化测试脚本、准备测试数据
- 线上问题排查
- 录制回放提供"昨日重现"能力,还原线上真实场景到线下做问题排查和Debug
- 动态方法入参/返回值录制,提供线上快速问题定位
- 压测流量准备
- 0成本录制HTTP/Dubbo等入口流量,作为压测流量模型进行压测
- 实时业务监控
- 动态业务监控,基于核心接口数据录制回流到平台,对接口返回数据正确性进行校验和监控
Java生态中间件及各种框架众多,目前适配了几款常用插件。详细看源码地址文档
2.AutoDiff
汽车之家自研 AutoDiff 进行黑盒流量回放测试 案例: AutoDiff流量回放在集成测试中的实践应用-汽车之家
3.rdebug
Rdebug 是滴滴开源的一款用于 RD 研发、自测、调试的实用工具,可以被用来提升 RD 研发效率、保障代码质量进而减少线上事故 源码:https://github.com/didi/rdebug
适用场景
- 适用于对已有接口进行代码重构、功能升级,且该接口已经有录制的流量。
- 不适合新开发的接口 或 未进行流量录制的接口。
- 支持新接口的方案在调研中。
4.GoReplay
GoReplay是用Golang写的一个HTTP实时流量复制工具。只需要在LB或者Varnish入口服务器上执行一个进程,就可以把生产环境的流量复制到任何地方, 比如Staging 环境、Dev环境。完美解决了HTTP层实时流量复制和压力测试的问题。
PS:tcp的录制与回放需要购买商业版
功能:
- 流量的放大和缩小、频率限制。这样不需要搭建和生产环境一致的服务器集群也可以正确测试
- 根据正则表达式过滤流量。意味着可以单独测试某个API服务
- 可以修改HTTP请求头,比如替换User-Agent, 或者增加某些HTTPHeader
- 把请求记录到文件,以备回放和分析
- 支持和ElasticSearch集成,将流量存入ES进行实时分析。
安装:
官网提供编译好的二进制文件,下载后解压即可使用。
下载:https://github.com/buger/goreplay/releases/download/1.3.3/gor_1.3.3_x64.tar.gz
解压: tar -zxvf gor_1.3.3_x64.tar.gz
复制二进制文件到系统命令中【必须】:cp gor /usr/local/bin
案例
# 简单的HTTP流量复制
gor --input-raw :80 --output-http "http://staging.com"
# HTTP流量复制频率控制(获取每秒超过10个请求)
gor --input-tcp :28020 --output-http "http://staging.com|10"
# HTTP流量复制缩小
gor --input-raw :80 --output-tcp "replay.local:28020|10%"
# HTTP流量记录到本地文件
gor --input-raw :80 --output-file requests.gor
# HTTP流量回放和压测。加快回放的时间2倍
gor --input-file "requests.gor|200%" --output-http "staging.com"
# 回放多个文件使用*
gor --input-file ./requests_*.gor --output-http "http://127.0.0.1:8080"
# HTTP流量过滤复制
gor --input-raw :8080 --output-http staging.com --output-http-url-regexp ^www.
# 自定义一些流量复制的参数
gor --input-raw :80 --output-http 192.168.2.6:8000 --http-allow-method POST --http-set-header 'User-Agent: Gor' -output-http-workers=1 -http-allow-url test.php
# 将流量复制两份到不同的测试服务
gor --input-tcp :28020 --output-http "http://staging.com" --output-http "http://dev.com"
# 将流量像负载均衡一样分配到不同的服务器
gor --input-tcp :28020 --output-http "http://staging.com" --output-http "http://dev.com" --split-output true
# 指定录制的时长
gor --input-raw :8080 --output-file ./requests.gor --exit-after 10s
离线录制的数据、目前工具不支持保持用户会话,所以需要我们在流量回放之前自行修改回放文件。 录制的文件的格式如下,我们可以把修改header,模拟其他环境的某个用户。
1 b2f40050c0a864904f59cc50 1689130244025192000 0
GET /login/index HTTP/1.1
Host: 192.168.100.4
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 12; CET-AL00 Build/HUAWEICET-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.102 MQQBrowser/6.2 TBS/046503 Mobile Safari/537.36 wxwork/4.1.7 MicroMessenger/7.0.1 NetType/WIFI Language/zh Lang/zh ColorScheme/Light
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/wxpic,image/sharpp,image/apng,image/tpg,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
X-Requested-With: com.tencent.wework
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
离线回放数据结果
[root@localhost data]# gor --input-file "./requests_*.gor|200%" --output-http "http://192.168.100.101:8080"
2023/07/12 14:29:53 [PPID 1843 and PID 1992] Version:1.3.0
[DEBUG][elapsed 2.647107892s]: [INPUT-FILE] FileInput: end of file './requests_*.gor'
5.TCPCopy
对于不是基于http协议的流量复制,可以使用流量复制工具TCPCopy, TCPCopy支持tcp协议流量的复制、转发、拦截,非常棒的工具。
TCPCopy项目地址:https://github.com/session-replay-tools/tcpcopy
TCPCopy是tcp回放工具,不具备录制功能,所以需要借助TCPdump录制tcp请求。
安装
1.TCPdump
在需要录制tcp的服务器上安装,比如生产的nginx服务器。
yum install -y tcpdump
2.Tcpcopy
在需要回放tcp的服务器上安装。
wget https://github.com/session-replay-tools/tcpcopy/archive/1.0.0.tar.gz
tar xvf 1.0.0.tar.gz
cd tcpcopy-1.0.0
./configure --prefix=/opt/tcpcopy/ --offline
make
make install
3.Intercept
Tcp的回放依赖,是回放的辅助机器,可以和Tcpcopy安装到一台服务器上。
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 --prefix=/opt/tcpcopy/ --offline
make
make install
使用教程
1.录制tcp
tcpdump -i enp0s3 tcp and port 8080 -w ./dump.pcap
-i eth0:eth0为网卡,获取方式可在liunx系统下执行ifconfig查看所有的网卡,选取需要的那个。
-w online.pcap:为获取pcap文件进行回放,可设置路径
tcp and port 80:截获端口为80的tcp请求
-s 0:默认的话,tcpdump只显示部分数据包,-s snaplen是控制包长度的,默认是68字节,-s 0 则为全部字节,在使用过程中,如果添加-s则回放时会出现错误。可不使用该参数
2.开启Intercept
/opt/tcpcopy/sbin/intercept -i enp0s3 -F 'tcp and src port 8080' -d
-i, intercept会监听端口,和tcpcopy进行通信,-i就是指定监听在哪个端口。tcpcopy启动的时候会来连这个端口,如果连不上,就会启动失败。
-F, 过滤规则,语法和pcap一样。
-d, 已守护进程方式运行
3.回放tcp
/opt/tcpcopy/sbin/tcpcopy -x 8080-192.168.100.101:8080 -s 192.168.100.101 -c 192.168.100.101 -i ./dump.pcap
-x, 是指本机8000端口的流量copy到192.168.100.101的8000端口
-s, 指定intercept机器的地址,tcpcopy要和intercept建立连接
-c 伪装地址,在把流量复制到测试服务器的时候,修改数据包的源地址为192.168.100.101,这样方便指定路由。也可以写成192.168.100.x,这样源地址就是指定网段中的地址了。
-i 指定需要回放的tcpdump文件
6.mitmproxy
源码:https://github.com/mitmproxy/mitmproxy
mitmproxy是一个交互式的、支持 SSL/TLS 的拦截代理,具有用于 HTTP/1、HTTP/2 和 WebSockets 的控制台界面。
mitmdump是 mitmproxy 的命令行版本。类似于 HTTP 的 tcpdump。
mitmweb是 mitmproxy 的基于 Web 的界面。
- 本文作者:zhangxue
- 本文链接:https://lucksnow1989.github.io/article/10.devOps/9.流量回放.html
- 版权声明:本文为本人原创文章,遵循 CC 4.0 BY-NC-SA版权协议,转载请附上原文出处链接和本声明。