前言
在日常的测试工作中我们或多或少总会遇到下列问题:
1)服务架构升级或重构,需要验证原始接口逻辑,对原有的一堆接口做回归
2)对于业务逻辑复杂的场景,每个迭代版本都需要大量的时间用于回归测试
3)编写自动化用例时复杂场景造数麻烦,日常自动化维护成本高
4)构造压测模拟数据麻烦
......等等
那么从服务的所有环境来看,仅线上环境拥有场景丰富、数据真实、覆盖全面的条件,那么我们将线上环境的请求数据获取下来,在指定的环境中模拟用户请求基本上可解决或者优化上面的这些问题。因此有必要需要对流量回放这项技术探究一下,首先从资料总结和自身搭建讲演来讲,总结流量回放的大概流程可为:流量录制 - 数据持久化 - 回放计划 - 环境维护 - 流量回放 - 结果比对。其次,所谓工欲善其事,必先利其器,下面我们看一些常用的流量回放分类以及工具的优缺点。
工具分类
根据流量录制的位置大致可分为:基于web服务器录制、基于应用层录制、基于网络协议栈录制。
web服务器录制
方案:在服务上定制化代码
优点:请求类型比较多样
缺点:不通用,维护成本高,会占用大量线上资源
应用层录制
方案:在网关或基于AOP切面进行录制
优点:对代码无侵入、实现相对比较快捷简单
缺点:会占用线上部分资源、可能会对业务有影响
常用工具:Nginx插件-ngx_http_mirror_moudle、Java-sandbox
网络协议栈录制
方案:直接监听网络端口,复制数据包方式录制
优点:基本对应用无影响
缺点:比较偏向底层实现成本较高
常用工具:goReplay、tcpCopy、tcpReplay
常用工具介绍
ngx_http_mirror_module
流量请求到nginx后,nginx正常转发请求到目标应用,同时复制流量到mirror服务后不再管控。
优点:
原生模块支持,在nginx 1.13.4版本后内置该模块
支持配置多份镜像放大流量
配置比较简单,nginx-server将流量复制到mirror后无交集,达到对真实流量无影响目的
缺点:
修改配置后需要执行“nginx -s reload”命令使变更生效,线上环境不建议这么做
实际业务中经由nginx转发的模块较多,无法筛选指定请求
只支持录制http流量
mirror为子请求,当mirror未结束时,主请求的内存无法释放,可导致nginx性能下降甚至阻塞
TcpCopy
项目地址:https://github.com/session-replay-tools/tcpcopy
流转示意图:
TcpCopy主要有tcpcopy和intercept两个模块组成,tcpcopy模块运行在线上机器,主要负责捕获在线请求并修改请求头中的目标地址和 源地址,然后使用raw socket输出技术发送数据包到目标服务器。目标服务器上根据配置的信息将响应数据包路由到intercept辅助服务器。intercept辅助将提取的响应头信息发送给tcpcopy。tcpcopy利用收到的信息修改捕获的数据包属性并发送至目标服务器。
优点:
- 使用线上的真实数据
- 适合高并发场景
- 对目标服务器基本无干扰
- 支持复制基于TCP任意层协议的流量
缺点:
- 由于只做数据包复制未做流量异常鉴别,可能导致异常数据进入目标服务器
- 无法对应用层的数据进行筛选和修改
- 可能会丢失数据包导致请求丢失
GoReplay
项目地址:https://github.com/buger/goreplay
GoReplay是基于Go语言实现与Tcpdump一样都是依赖pcap库,主要监听网络接口流量来录制流量,支持在线和离线方式回放流量
优点:
- 轻量程序基本无需配置,环境准备简单
- 程序资源消耗少,无侵入应用运行环境
- 提供不限制语言的插件机制,方便拓展
缺点:
- 社区版仅支持录制http协议,且与核心逻辑耦合,应用面不广泛
- 大公司使用少,整体成熟度不高
Jvm-sandbox-repeater
项目地址:https://github.com/alibaba/jvm-sandbox-repeater
使用jvm-sandbox沙箱技术,通过Java agent或者attach方式挂载到Java应用上。repeater模块根据配置的规则录制或回放数据,console模块主要负责触发和数据交互。
优点:
- 通过字节码增强的方式可以直接录制Java方法、子调用
- 对业务代码0侵入
- 模块功能丰富
缺点:
- 对服务运行环境有一定侵入
- 在挂载瞬间会占用较多的机器资源,当业务量大时可能会导致服务夯住
- 当前功能不完善,需要代码开发能力
总结
通过技术方案可以方便我们利用线上真实流量验证压测、自动化、回归等场景,根据自己实际的需求选择合适的工具,但一切以不影响线上服务的稳定可用为前提。也期待后续会有更多的更完善的流量回放方案。