真实流量压测工具 tcpcopy应用浅析

极为合理的测试需求

“双一十”将近,作为一个电商应用的开发人员,也是时候操心一下自己管理服务的性能问题了。平时跑得好好的服务应用,能否承受的住双十一,尤其是午夜时刻的流量冲击?到底是要加机器还是要做服务降级?机器加多少?服务降级降多少.....为回答这一系列的问题,你首先要知道服务的极限是多少。按我们这种非专业测试人士的设想,测试方法应满足如下需求:

  • 给出简单可量化的测试结果,最好直接是告诉我被测服务的极限是正常流量的几倍。
  • 不是对单一接口的测试,而是对服务整体的测试。
    服务程度一般都会提供多种接口。很多测试工具,都只是对单独的接口进行测试,这种得出的结果是单独服务接口的极限,而非你的服务程序整体的对外性能情况。而且现实情况会很复杂,比方说,搜索服务中的商品搜索接口的极限TPS权限是1000,而商品详情接口的极限TPS是8000,有了这些数据你还是不知道要加多少台机器。很有可能由于你的外部调用策略以及用户潜在的使用习惯分布,总体搜索接口的调用次数与商品详情的调用次数有着稳定有比例关系,而你很可能对这些内在关联不得所知。这也就要求你的测试数据要符合真实用户产生的各接口请求的数量分布。
  • 考虑缓存的情况,不能简单地重复测试数据或遍历表。
    缓存是缓解服务器压力的重要手段,但又很容易在测试环节中引起人们对于服务器能力的错误判断。如果你只是简单地利用少量重复数据做为参数进行请求,这样会请求结果大都会从缓存直接返回,使你高估服务器能力;如果你通过直接遍历表或者生成随机数据的方式做为请求参数,则会使缓存命中过低,测试结果也无法代表服务的真实能力。
  • 测试数据的分布要尽可能地符合真实用户请求分布。

面对这多么的要求,如何获取测试数据就成了最大的问题。Tcpcopy提供的解决方案是从线上复制真实的测试流量进行测试,同时尽可能减小对线上服务的影响。

 

tcpcopy1.0.0架构



 

TCPCopy实际由两部份组成:tcpcopy和intercept。
tcpcopy运行在线上服务器,负责捕捉和复制线上请求到待测试服务。
intercept负责在辅助服务器上进行响应包的截获,并通过intercept程序返回响应包的必要信息(一般为TCP/IP头部信息)给tcpcopy。由于tcp交互是相互的,一般情况下需要知道测试服务器的响应数据包信息,才能利用在线请求数据包,构造出适合测试服务器的请求数据包,因此只要基于数据包的方式,都需要返回响应包的相关信息。
此外,intercept所在的辅助服务器,扮演了黑洞的角色。复制过来的请求从待测试服务机上的响应包都会被路由到intercept所在的辅助服务上(需要在待测试服务器上配置route规则),为了防止响应返回到线上的真实客户端,这些响应数据包需要被丢弃掉。之前版本的intercept通过netlink协议,采用ip queue或者nfqueue在内核态捕捉响应数据包,发送给intercept进程,由intercept告知内核裁决结果(ACCEPT,DROP)。这种方式容易出现性能瓶颈。1.0.0版本中丢包的方法就显得更省力多了,要求辅助服务器关闭ip_forward,这样响应包自然就发不出去了。

 

tcpcopy 实践

1. 实验环境

待测试服务(target server): 地址199.155.122.162 ,端口8080
多台线上服务 (online server): 地址199.155.122.196,端口 8082
地址199.155.122.195,端口8082
辅助机器(assistant server): 199.155.122.233
另外提供一个用于伪装的源地址:199.155.122.200

2.在assistant server上安装 intercepter

https://github.com/session-replay-tools/intercept/releases 下载 intercepter1.0.0.zip文件解压。随后运行。
如果遇到如下失败提示:
checking for pcap.h ... not found
需要事先安装libpcap-delvel
yum install libpcap-devel
然后执行 make & make install 搞定

3.在online server上安装tcpcopy

https://github.com/session-replay-tools/tcpcopy/releases 下载tcpcopy1.0.0.zip文件解压。
运行./configure
再执行make & make install 搞定

4.开始流量复制

  • 在target server (199.155.122.162)下加入route规则:
    route add -host 199.155.122.200 gw 199.155.122.233
    199.155.122.200是经复制后测试数据包上填入的源地址。199.155.122.233为assistant server,上面将会运行intercept服务。这条命令作用是 target server对于复制而来的请求(根据源地址判断)的响应,不会返回给请求客户端,而是发往assitant server这个统一的垃圾站。

  • 在assistant server( 199.155.122.233)运行命令(需要root权限):
    ./intercept -i eth0 -F 'tcp and src port 8080' –d
    然后关闭linux转发功能:
    echo "0" > /proc/sys/net/ipv4/ip_forward
    其中8080是target server的端口号。
    我们可以执行ps –aux|grep intercpet查看是否已经启动成功。

  • 在online server执行(199.155.122.196,199.155.122.195 ):

    ./tcpcopy -x 8082-199.155.122.162:8080 -s 199.155.122.233 -c 199.155.122.200
    其中8082是target server的端口号。
    -x 8082-199.155.122.162:8080 是将从8082端口的请求发往 target server。
    -s 199.155.122.233 为指定assistant server。
    -c 199.155.122.200 是指将所有复制请求的数据包的源地址全改为199.155.122.200。
    修改原地址的好处是:很多时候,client的是四处分布的,不一定固定的几个ip,统一设计为一个源地址,便于在target server上route规则的设置。
    这里我们复制了两台线上服务的请求,就相当于发送给对测试机了两倍线上请求流量进行压测。
    如果你想要复制更多倍数的线上服务流量可以使用-n参数指定复流量的倍数。

5.如何查看是否生效

可以采用dstat 命令查看,网络流量是否增加。
也可以安装nethogs,查看指定端口网络实时流量。如果target server 8080端口的流量是online server 8082端口流量的两倍,说明上述操作成功。

6.停止流量复制

停止流量复制的方法很简单,
在assistant server 中kill intercept进程,在online server 中kill tcpcopy进程,在target server上删除相应的route。

 

效果展示

以下我们对某线上集群服务中的单台节点做压力测试的结果。
先是从其他两上结点复制流量,相当于三倍流量效果,明显可以看到network上升。随后是load和平均响应时间上升,随后稳定。



 

 

 

 

经过一天稳定运行后,加大压力,复制4台线上结点的流量,承受5倍的流量。很快就出现了load的飙升。我们的服务已经被压垮了。



 

 

 

参考文章:
1、http://blog.csdn.net/wangbin579/article/details/8950282
2、http://blog.csdn.net/wangbin579/article/details/8949315
3、github 地址https://github.com/session-replay-tools/tcpcopy

20151016首发于3dobe.com:http://3dobe.com/archives/174/

本站链接  http://quentinXXZ.iteye.com/blog/2249799

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TCP(传输控制协议)是一种面向连接的协议,用于在网络上可靠地传输数据。它提供了数据的可靠传输、流量控制和拥塞控制等功能,是互联网的核心协议之一。 在Node.js中,使用内置的net模块可以轻松地创建TCP服务器和客户端。下面是一个简单的TCP服务器示例: ```javascript const net = require('net'); const server = net.createServer((socket) => { console.log('client connected'); socket.on('data', (data) => { console.log(`received data: ${data}`); socket.write(`echo: ${data}`); }); socket.on('close', () => { console.log('client disconnected'); }); }); server.listen(3000, () => { console.log('server started on port 3000'); }); ``` 这个服务器会监听本地的3000端口,当有客户端连接时,会打印出“client connected”的信息。当客户端发送数据时,服务器会收到这些数据并将其打印到控制台上,然后将“echo: ”加在数据前发送回客户端。当客户端断开连接时,服务器会打印“client disconnected”的信息。 下面是一个简单的TCP客户端示例: ```javascript const net = require('net'); const client = new net.Socket(); client.connect(3000, 'localhost', () => { console.log('connected to server'); client.write('hello, server'); }); client.on('data', (data) => { console.log(`received data: ${data}`); client.destroy(); }); client.on('close', () => { console.log('disconnected from server'); }); ``` 这个客户端会连接到本地的3000端口,并发送“hello, server”的消息。当客户端收到服务器的响应时,会打印出这些数据,并断开连接。 总的来说,TCP在网络通信中扮演着非常重要的角色,Node.js内置的net模块提供了简单易用的TCP套接字接口,使得我们可以轻松地创建TCP服务器和客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值