https://blog.csdn.net/ronmy/article/details/65657691

TCPCopy是一种请求复制(所有基于tcp的packets)工具,可以把在线请求导入到测试系统中去。目前此工具已经广泛应用于国内各大互联网公司。

TCPCopy七大功能
1)分布式压力测试工具,利用在线数据,可以测试系统能够承受的压力大小(远比ab压力测试工具真实地多),也可以提前发现一些bug
2)普通上线测试,可以发现新系统是否稳定,提前发现上线过程中会出现的诸多问题,让开发者有信心上线
3)对比试验,同样请求,针对不同或不同版本程序,可以做性能对比等试验
4)流量放大功能
5)利用TCPCopy转发传统压力测试工具发出的请求,可以增加网络延迟,使其压力测试更加真实
6)热备份
7)实战演习(架构师必备)

TCPCopy的特点
1)实时 (离线通过configure --enable-offline)
2)效果真实
3)低负载,不影响在线
4)操作简单
5)分布式
6)零成本

TCPCopy使用方法
TCPCopy分为TCPCopy client(即tcpcopy)和TCPCopy server(即intercept)两部分。

其中TCPCopy client运行在在线服务器上面,用来捕获在线请求数据包;

TCPCopy server(默认监听端口为36524)运行在测试机器上面,用来截获响应包,并传递响应包头信息给TCPCopy client,以完成TCP交互。

TCPCopy使用分为传统使用方式和高级使用方式:

传统使用方法:

TCPCopy server (root用户执行)
采用IP Queue 模块(内核<3.5,默认采用IP Queue):
1)启动内核模块ip_queue

1
modprobe ip_queue

 

2)设置要截获的端口,并且设置对output截获

iptables -I OUTPUT -p tcp --sport port -j QUEUE

3)运行intercept程序:

./intercept

intercept 常用参数:

-d 参数:可以设置 tcpcopy,intercept 以 daemon 运行 ;

注意,测试完毕需要在测试设备上执行:

iptables -L --line
iptables -D OUTPUT 1 #删掉 刚才加入的规则

或者采用NFQueue 模块(内核>=3.5,默认采用NFQueue):
1)设置iptables:

 iptables -I OUTPUT -p tcp --sport port -j NFQUEUE 

2) 运行intercept程序:

./intercept

TCPCopy client (root用户执行)

./tcpcopy -x 服务器应用端口号-测试服务器ip地址:测试服务器应用端口

tcpcopy 常用参数:

-x <transfer,> 
Transfer 具体格式如下 : 
服务器对外IP地址 : 服务器应用端口号 - 测试服务器 IP 地址 : 测试服务器应用端口 tcpcopy -x 80-42.62.30.205:80

-n 参数:

如果你要进行多重复制,那么此参数的值就是代表复制过去的流量是在线的n倍,倍数小,效果越好,因为多重复制的原理是修改端口号,因此复制的倍数越大,端口冲突的概越大,特别是源IP地址非常少,短连接的的内网应用场合。系统默认最大值为 1023 倍。
举例:

./tcpcopy -x 80-192.168.0.2:8080 -n 3

-r 参数:
如果你想复制在线服务器应用的部分流量,可以采用-r参数来实现,参数范围是1~99 ,其它值都是全流量复制。
举例:

./tcpcopy -x 80-192.168.0.2:8080 -r 20    #复制20%的量

传统使用方式注意事项:

(源代码转移到了github,敬请注意)

1)Linux平台,内核2.6+,目前tcpcopy传统架构需要支持netlink机制或者nfqueue(0.6.5版本+支持
nfqueue,在./configure指定nfqueue即可或者对于0.7.0+版本,如果内核为3.5+,则自动采用nfqueue模式)

2)TCPCopy中的tcpcopy和intercept程序运行需要root权限

3)intercept在同一台机器只需要运行一个实例就能支持多个应用的复制(设置多条iptables命令)

4)TCPCopy client需要连接测试服务器(默认36524端口),所以要对外开放相应端口

5)TCPCopy由于依赖于抓包函数,压力大的时候,抓包函数本身不可靠,所以会丢包,进而丢失请求

6)如果采用的是IP Queue模块来截获响应包,则intercept程序密切跟ip queue内核模块相关,
所以当压力很大的时候请求丢失率很高,需要优化sysctl系统参数才能达到好的效果
(通过cat /proc/net/ip_queue,查看ip queue运行情况,如果Queue dropped的数值不断增大,
则需要修改ip_queue_maxlen参数,比如echo 4096 > /proc/sys/net/ipv4/ip_queue_maxlen;
如果Netlink dropped的数值不断增大,修改net.core.rmem_max和net.core.wmem_max参数,
比如sysctl -w net.core.rmem_max=16777216和sysctl -w net.core.wmem_max=16777216)

7)如果要复制127.0.0.1发出的请求到另外一台机器,需要设置-c参数

8)测试环境最好和在线环境一致,比如连接都保持keepalive

9)TCPCopy只与ip、tcp层的数据有关,如果请求验证与tcp层以上的协议有关,则系统不能正常运行。
例如:mysql连接协议,由于权限认证与tcp层上面的mysql协议有关,所以复制过去的请求会被目标测试
服务器认为非法请求,这个时候需要针对mysql协议作具体针对性的处理,tcpcopy程序才能正常运行

10)多层架构环境下,测试系统一定要独立,与在线系统没有业务关联,否则会影响在线

11)丢失请求率跟网络状况有关,最好在内网内复制请求

12)本系统不支持域名,只支持ip地址

13)更多信息参考如下文档
(http://tcpcopy.googlecode.com/files/TCPCopy_Manual_v0.9.6%28Chinese%29.pdf.pdf)

高级使用方式:
参考:
http://blog.csdn.net/wangbin579/article/details/8950282
http://blog.csdn.net/wangbin579/article/details/8994601
http://blog.csdn.net/wangbin579/article/details/10148247


TCPCopy架构和工作原理

基于server的请求回放领域,一般分为离线回放和在线实时复制两大领域,一般研究者都是从离线回放的角度在苦苦研究,而在实时复制领域,研究非常少。

请求实时复制,一般可以分为两类:

1)基于应用层的请求复制
2)基于底层数据包的请求复制

传统的做法一般从应用层面进行复制,比如基于服务器的请求复制,这种复制的好处就是实现起来相对简单,但也存在着若干缺点:
1)请求复制从应用层出发,穿透整个协议栈,这样就容易挤占应用的资源,比如宝贵的连接资源;
2)测试跟实际应用耦合在一起,容易导致对在线系统的影响,比如有些基于服务器的复制,会导致用户请求的处理时间取决于最慢的请求处理时间(max(真正的请求处理时间,被复制的请求请求处理时间));
3)很难支撑压力大的请求复制(据若干用户反映,这种类型的请求复制,曾经严重影响在线系统);
4)很难控制网络延迟;

基于底层数据包的请求复制,可以做到无需穿透整个协议栈:

路程最短的,可以从数据链路层抓请求包,从数据链路层发包,

路程一般的,可以在IP层抓请求包,从IP层发出去;

不管怎么走,只要不走TCP,对在线的影响就会小得多。

进入正题,tcpcopy是如何进行架构演化的呢?

tcpcopy架构已历经三代,基本原理都一样,本质是利用在线数据包信息,模拟tcp客户端协议栈,欺骗测试服务器的上层应用服务。由于tcp交互是相互的,一般情况下需要知道测试服务器的响应数据包信息,才能利用在线请求数据包,构造出适合测试服务器的请求数据包,因此只要基于数据包的方式,无论怎么实现(除非是tcp协议改的面目全非),都需要返回响应包的相关信息。

三种架构的差别就在于在什么地方截获响应包

我们先看看tcpcopy最初的架构:

从上图可以看出,tcpcopy是从数据链路层(pcap接口)抓请求数据包,发包是从IP层发出去,测试服务器的TCP协议栈没有类似ip queue或者nfqueue的干扰,响应包会直接返回给在线机器(通过设置路由),tcpcopy可以在数据链路层捕获到这些响应包,这些响应包会到达IP层,一般最终被丢弃掉(除非是客户端IP地址就是这台在线机器的IP地址,会通过IP层,但会被TCP reset掉)。

回到正题,这种架构一般只能工作在同一网段,而且对于外网应用,一般只能复制单台在线流量给测试服务器,无法对网易广告投放系统进行深度问题发现和潜能挖掘。

第一种架构总结如下:
好处:
1)简单,粗暴
2)适合冒烟测试
3)测试结果比较真实

不好的地方:
1)相对而言,会更加影响在线,因为响应包信息全部回给在线机器了(当然这种还是比应用层面的请求复制,影响更小)
2)同一网段限制
3)对于外网应用,无法充分利用或者很难充分利用多台在线流量,从而无法为压力测试提供技术支持
4)内网应用严重受限制,因请求的客户端IP地址不能是被复制的在线机器的IP地址

第二种架构,也就是目前开源的架构,设计也是tcpcopy鼻祖王波同学设计(2010年设计出来,2011.6月设计移交给多人,包括我),大致架构如下:

从上面图中我们可以看出,tcpcopy默认从IP层抓包,从IP层发包,与第一种架构不同的是,我们在测试服务器进行响应包的截获,并通过intercept程序返回响应包的必要信息给tcpcopy。这种架构为分布式压力测试提供了可能性,相比第一种架构,大大推动了tcpcopy的进化。

我们先从响应包的截获来分析,理论上,可以在测试服务器的IP层或者数据链路层进行截获响应包,我们具体分析如下:

1)在数据链路层抓,正常情况下,其响应数据包会返回给真正发起请求的客户端,这会或多或少影响到客户端的TCP(频繁地reset)模块,而且在压力大的时候,会给交换机、路由器甚至整个网络,带来不必要的干扰。

2)在测试服务器的IP抓响应包,正好有netlink技术来解决上面的问题,netlink是一种用户态进程与内核进行交互的技术,具体地我们可以利用内核模块ip queue(内核3.5以下版本)或者nfqueue(内核3.5或者以上版本)来达到捕获响应包的目的。

我们采用了第二种方式,也即上图中的IP层来截获响应包,当响应包传递给intercept后,我们就能copy到响应包信息的必要信息(一般为TCP/IP头部信息),传递给tcpcopy,我们还可以通过verdict告诉内核,该如何处理这些响应包,如果没有设置白名单的话,就会在IP层丢弃掉这些响应包,这时候你是无法利用tcpudmp来抓到这些响应包的(tcpdump工作在数据链路层)。

这种设计的好处就是可以支持复制多台在线流量到一台测试服务器中去,我们在intercept保留路由信息,知道响应包的相关信息该如何返回给哪一个tcpcopy实例。然而这种架构,intercept会不同程度地占用测试服务器的资源,而且ip queue或者nfqueue,并不一定能够高效工作,因而给测试,特别是高压测试和短连接压力测试,带来了很大麻烦。

这种架构总结如下:
好处:
1)支持复制多台在线流量
2)影响在线机器更小,因为一般只需要返回TCP/IP头部信息

不好的地方:
1)较第一种更为复杂
2)性能极限往往在ip queue或者nfqueue
3)intercept扩展性不好,受制于ip queue和nfqueue无法支持多进程进行响应包的捕获操作
4)intercept影响测试服务器的最终测试结果,特别是压力大的时候
5)无法对测试服务器进行完整测试(没有覆盖到数据链路层的出口)
6)运维不方便

第三种架构,如下图:

上述架构,也即最新架构,是为了极限测试的目的而设计的,把intercept的工作从测试服务器(test server)中offload出来,放到另外一台独立的辅助服务器(assistant server,原则上一定要用同网段的一台闲置的服务器来充当辅助服务器)上面进行截获响应包,而且把原先从IP层捕获响应数据包的工作转移到从数据链路层抓响应包,这些改变大大降低了对测试机器的各种干扰(除了路由设置,其它已经没有影响了),而且大大扩大了捕获响应包的能力。当然这种测试也更加真实。

具体如下:

在运行上层服务的测试服务器test server上面设置路由信息,把待测试应用的需要被捕获的响应数据包信息路由到辅助服务器assistant server 上面,在assistant server上面,我们在数据链路层截获到响应包,从中抽取出有用的信息,再返回给相应的tcpcopy。

为了高效使用,这种架构推荐使用pcap进行抓包,这样就可以在内核态进行过滤,否则只能在用户态进行包的过滤,而且在intercept端或者tcpcopy端设置filter(通过-F参数,类似tcpdump的filter),达到多个实例来共同完成抓包的工作,这样可扩展性就更强,适合于超级高并发的场合。

这种架构需要的机器资源也更多,而且也变得更加难使用,需要了解tcp知识,route知识和pcap filter知识(类似于tcpdump过滤条件),因此推荐有条件的并且熟悉上述知识的人使用最新的架构。

需要注意的是,在某些场景,pcap抓包丢包率会远高于raw socket抓包,因此tcpcopy出现大量“unsend:too many packets”的报警,请采用raw socket方式来抓包(tcpcopy采用./configure --enable-advanced,而intercept 采用./configure --enable-advanced --enable-pcap)。

总结如下:
好处:
1)更加真实
2)可扩展性更强
3)适合高并发场合
4)无ip queue或者nfqueue的各种限制
5)对测试服务器几乎没有任何性能干扰的影响
6)在运行服务的测试服务器,运维更加方便
7)不会随运行服务的服务器崩溃而崩溃

不好的地方:
1)操作难度更大
2)需要的机器数量更多
3)需要的知识也更多
4)assistant server(运行intercept的机器)原则上必须要和测试服务器(test server)在同一个网段

上面三种架构均具有价值,目前开源出来的仅仅包括第二种架构和第三种架构,tcpcopy默认采用第二种架构,有条件的可以采用第三种架构。

对于如何采用新架构,参考http://blog.csdn.net/wangbin579/article/details/8950282

最后,对于请求复制,要想达到对在线没有影响或者影响尽可能小,可以采用如下对策:

利用高性能的旁路机制(如果采用镜像,需要改客户端数据包的目的地址),复制请求数据包到另外一个独立的系统,在这个独立的系统,我们采用第三种架构,进行请求的捕获,再复制给测试服务器上面的应用。

 
 
 
官网地址 https://github.com/session-replay-tools/tcpcopy 里面有包的下载地址、文档 和常见问题

【测试环境】TCPCopy 使用方法的更多相关文章

  1. [软件测试]Linux环境中简单清爽的Google Test (GTest)测试环境搭建(初级使用)

    本文将介绍单元测试工具google test(GTEST)在linux操作系统中测试环境的搭建方法.本文属于google test使用的基础教程.在linux中使用google test之前,需要对如 ...

  2. 使用tcpcopy拷贝线上流量压测测试环境

    tcpcopy项目地址:https://github.com/session-replay-tools/tcpcopy 作者地址:http://blog.csdn.net/wangbin579 1:环 ...

  3. TCPCopy 使用方法

    TCPCopy 使用方法 TCPCopy是一种请求复制(所有基于tcp的packets)工具,可以把在线请求导入到测试系统中去.目前此工具已经广泛应用于国内各大互联网公司. TCPCopy七大功能 1 ...

  4. iOSIPV6简单测试环境搭建

    应苹果官方要求,iOS应用必须适配IPV6才能通过审核,这里分享一个简单的ipv6测试方法 一.工具原料 1.1 Mac电脑一台 1.2 iPhone手机两部 1.3 数据线一根 二.步骤方法 2.1 ...

  5. NodeJs 开发微信公众号(二)测试环境部署

    由于卤煮本人是做前端开发的,所以在做公众号过程中基本上没有遇到前端问题,在这方面花的时间是最少的.加上用了mui框架(纯css界面)和自己积累的代码,很快地开发出了界面来.接着是后台开发.卤煮选的是n ...

  6. Rails的三种环境----开发环境,生产环境和测试环境

    Rails 的三个环境 Rails 的应用程序预设提供了三种不同的执行模式: development environment 开发模式,用在你的开发的时候 test environment 测试模式, ...

  7. 第五章 搭建 S3C6.410 开发板的 测试环境

    一.简介: 对于嵌入式驱动开发者来说,你必须要了解什么是开发板:它与我们经常用的手机类似, 包含了显示屏. 键盘. Wi-Fi. 蓝牙等模块等,是开发者必备的硬件设备.但与手机不同的是:在开发板上安装 ...

  8. 第五章——搭建S3C6410开发板的测试环境

    搭建S3C6410开发板的测试环境 通过本章的学习学会了如何在开发板上安装Android.开发板是学习和开发嵌入式技术的主要硬件设备,想要顺利的通过linux驱动访问硬件,是不能在PC板上模拟的,需要 ...

  9. 使用Nodejs+Protractor搭建测试环境

    Protractor是一个end-to-end的测试框架,从网络上得到的答案是Protractor是作为Angular JS应用程序的测试框架.它的构建基于Selenium WebDriver之上,且 ...

随机推荐

  1. 文献引用 .bib文件里有公式符号

    问题: 有时候文献标题带有特殊公式符号,进行BibTex编译时,会识别不出来公式符号. 例如: .bib文件里的文献: @article{XIE201892, title = "ℋ∞ con ...

  2. oracle中更新关键字merge和 with as关键字

    merge是oracle特有的语句,两表关联操作(增.删.改)就效率非常高 merge into table_name alias1 using (table|view|sub_query) alia ...

  3. [EOJ Monthly2019.11][T1]纸条

    https://acm.ecnu.edu.cn/ 华东师范大学在线评测网站 今天这个题目来自华东师范大学的校赛,比icpc稍难一些,在2019年11月29日周五19:30开始,持续2.5个小时 以下是 ...

  4. SpringMVC的 transferTo使用

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——SpringMVC其中的一个优势.Spring通过对Servl ...

  5. C++入门经典-例6.11-使用指针变量遍历二维数组

    1:代码如下: // 6.11.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #inc ...

  6. 【学习】windows 下PostgreSQL导入sql文件

    在软件的安装目录的bin文件下打开命令行工具 输入: psql -d 数据库名称 -h 数据库地址 -p  5432  -U  postgres  -f  sql文件(E:\Config\SQL\iS ...

  7. Zookeeper(一)客户端

    Zookeeper-客户端 例子: // org.apache.zookeeper.ZooKeeperMain public class ZooKeeperMain { public static v ...

  8. TCP定时器 之 坚持定时器

    坚持定时器在接收方通告接收窗口为0,阻止发送端继续发送数据时设定. 由于连接接收端的发送窗口通告不可靠(只有数据才会确认,ACK不会确认),如果一个确认丢失了,双方就有可能因为等待对方而使连接终止:接 ...

  9. ClientScriptManager 和 ScriptManager RegisterClientScriptBlock

    ClientScriptManager.RegisterOnSubmitStatement(Type, String, String) Method Registers an OnSubmit sta ...

  10. Spring配置多个数据源,并实现数据源的动态切换转载)

    1.首先在config.properties文件中配置两个数据库连接的基本数据.这个省略了 2.在spring配置文件中配置这两个数据源: 数据源1 <!-- initialSize初始化时建立 ...