文章首发公众号「码农吴先生」, 欢迎关注,及时获取更多技术干活~
「流量复制」经常应用在准生产环境的测试中,将线上的流量复制到一个准生产环境服务中,测试新功能和服务的承压能力。流量复制能够彻底模拟线上的流量,对复杂的业务场景进行真实的服务测试,又不会对生产服务产生任何反作用。python
对于复杂的流量复制应用场景和需求,彻底能够立项开发一套完整的复制架构,可参考字节团队自研的 ByteCopy 项目。而对于一些简单的需求,开源的工具基本能够搞定。开源的流量复制工具备不少,经常使用的有 goreplay、tcpreplay、tcpcopy 等。nginx
本文主要来探讨下 tcpcopy 和 goreplay 的方案实现,废话很少说开整。git
tcpcopy 由网易技术部王斌等开发,并于 2011 年 9 月开源的。tcpcopy 最新架构以下(来自做者王斌博客:https://blog.csdn.net/wangbin...):github
tcpcopy 主要有两个组件构成 tcpcopy client 和 intercept 。client 端负责复制流量和转发,intercept 负责对回应流量的拦截和 tcpcopy 的连接处理。golang
实例环境以下,下面来阐述下整个架构的搭建过程:ubuntu
各组件可直接从 github 下载源码包,编译安装:bash
# 起压机部署 tcpcopy client 192.168.33.11 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 make make install # 辅助机部署 intercept 192.168.33.12 , 截获包须要依赖 libpcap 抓包函数库 yum -y install libpcap-devel # ubuntu # apt install -y libpcap-dev 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/ make make install
安装完以后,先启动 intercept,运行以下命令:服务器
/opt/tcpcopy/sbin/intercept -i enp0s8 -F 'tcp and src port 8000' -d # -i,指定网卡 enp0s8 # -F,过滤,语法和pcap抓包工具一直,如tcpdump # -d,以domain的形式启动。 # 其余参数可 -h 查看。
启动 intercept 以后,再启动 tcpcopy client 。tcpcopy 启动依赖 intercept ,启动时确保 intercept 启动成功。网络
/opt/tcpcopy/sbin/tcpcopy -x 8000-192.168.33.13:8000 -s 192.168.33.12 -c 192.168.1.x -n 2 -d # -x,复制本地8000端口的流量,转发到192.168.33.13机器的8000端口 # -s,辅助服务器intercept 地址 # -c,修改转发包的原地址为该地址段的地址,这里也能够是明确的ip。这个ip端用来假装数据包,方便intercept作路由劫持。 # -n,流量倍数 # -d,以domain的形式运行
在测试服务器添加拦截路由,以下:session
# 测试机 192.168.33.13 route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.33.12
该路由至关于把到 192.168.1.0 网段的包都走网关 192.168.33.12,对测试服务器的回包作伪地址拦截。
这即是 tcpcopy 的整个架构部署了。
下面咱们抓包看看这个过程当中包是如何流动的。
我在 tcpcopy client 机器 192.168.33.11 和测试机器 192.168.33.13 使用 python -m SimpleHTTPServer
分别起了一个 8000 端口的服务用来测试,从我本机 192.168.33.1 发送请求,在三台机器上抓包。
tcpcopy client 机器 192.168.33.11 包信息以下:
红色标注块为我本机(192.168.33.1)和 tcpcopy client 机器(192.168.33.11)的正常请求交换,从三次握手,到 http 请求,到最后的断链。
蓝色标注块则为 tcpcopy 复制的流量,能够看到为了让 intercepter 拦截回包流量,tcpcopy 已将包源 ip 地址替换为咱们指定的伪网段(192.168.1.0)的地址,这样在回包时,就会根据测试服务器上的路由将回包指向辅助服务器 intercept,避免对生产流量形成影响。这也是为何复制流量三次握手和 http 都没有回包的缘由。
看测试服务器 192.168.33.13 的包:
测试服务器的包和正常流量包同样,三次握手到 http 请求,最后断连。这里和测试服务器 192.168.33.13 交互的源地址 ip 已经被 tcpcopy 替换为伪 ip 192.168.1.1 。
看 intercept 192.168.33.12 的包:
能够看到辅助服务器拦截下来的请求,标注块 1 为复制流量三次握手时的回包,标注块 2 为 http 请求的回包,这即是 intercept 的拦截功能。能够看到在标注块 一、2 以后,辅助服务器(192.168.33.12)和 tcpcopy 服务器(192.168.33.11)进行了数据交换,这部分即是 intercept 的 tcp 处理功能,它把有用的信息返回给 tcpcopy 以便能使 tcpcopy 和测试机的 tcp 连接完成。
根据上边抓包,咱们获得了和架构图同样的包流动过程,总结以下:
根据官方文档,咱们还须要注意几个问题:
ip_forward
Goreplay 是另外一个比较经常使用的流量复制开源工具。与 tcpcopy 相比它的架构更简单,只有一个 gor 组件,以下:
只须要在生产服务器上启动一个 gor 进程,它负责全部的工做包括监听、过滤和转发。
它的设计遵循 Unix 设计哲学:_一切都是由管道组成的,各类输入将数据复用为输出_。
输入输出一般被成为插件,常见的有下面几种。
可用输入:
可用输出:
你能够对数据进行限速、过滤、从新,还能够重用中间件实现一些自定义逻辑处理,如私有数据的过滤、认证等个性需求。
其余经常使用参数:
本文不对中间件作过多描述,仅讨论经常使用功能,对中间件有需求的可参考中间件文档。
Goreplay 是使用 golang 开发的,咱们能够直接使用编译好的对应各系统的二进制文件,也能够本身编译,咱们这里直接使用二进制文件。
wget https://github.com/buger/goreplay/releases/download/v1.3.0_RC1/gor_1.3_RC1_x64.tar.gz tar zxvf gor_1.3_RC1_x64.tar.gz # 解压出二进制文件 gor gor
接下来,直接启动 gor 便可复制流量和转发。
sudo ./gor --input-raw :8000 --output-http="http://192.168.33.13:8001"
复制本地 8000 端口的流量到 http 远端服务http://192.168.33.13:8001
。(复制同端口的流量时,流量会重复。这是 gor 的一个 bug,截止目前 1.3 版本仍可复现,可见issue292)
goreplay 的流量转发,并非直接 tcp 包的转发,而是从新组织 http 协议级别的请求,发送到测试服务器。因此它是新的 gor 线程和测试服务器的交互,和监听线程无关,因此无需对流量进行拦截。
下面咱们来看下 gor 复制的流量包的流向过程:
红色标注块为正常流量,蓝色标注块为复制的流量。
看到此处,你可能会有疑问,为何 gor 不用拦截流量?
你们仔细看 tcpcopy 和 gor 复制流量的端口,在生产机和测试机创建链接时,tcpcopy 虽然修改了 tcp 包的源 ip,但端口仍是用的请求客户端的端口,是 tcp 数据链路层级别的流量复制。而 gor 这里严格来讲并非复制,而是从新构建了 http 请求。使用新端口来和测试机建连,相对的测试机在回包时,即便包是回到了生产机,但因为是和客户端不一样的端口,也不会对生产流量形成影响。
到此,咱们对流量复制有了些基本的概念和应用了,也对 tcpcopy 和 goreplay 两款开源工具备了必定的认知。两款开源工具各有优缺点,咱们来一块总结下。
简单 http 复制 goreplay 彻底能够胜任,稍复杂点或应用场景更复杂,那么推荐 tcpcopy。更复杂,要求更高的流量复制,那只能咱们本身定制了。
好了,本篇到这结束了,欢迎留言讨论,你觉着最佳流量复制方案。
我是DeanWu,一个努力成为真正SRE的人。
关注公众号「码农吴先生」, 可第一时间获取最新文章。回复关键字「go」「python」获取我收集的学习资料,也可回复关键字「小二」,加我wx拉你进技术交流群,聊技术聊人生~