性能测试工具 gor 引流快速入门

胡刚 · 2016年02月06日 · 最后由 咕咕鸡 回复于 2019年09月11日 · 5817 次阅读
本帖已被设为精华帖!

0.背景

校验系统的正确性和可靠性时,仅靠用例场景无法覆盖全生产环境下的所有场景,需要一套引流工具,在系统正式上线前,用线上的请求测试待上线系统,在正常请求下,是否有报错;在数倍请求下,系统的性能瓶颈。引流工具有gor, tcpcopy等,下面介绍 gor,因为其易上手,且功能比较全。

1.golang 环境

1-1.下载 go

https://golang.org/dl/

[root@10 ~]# wget --no-check-certificate --no-cookie  https://storage.googleapis.com/golang/go1.5.3.linux-amd64.tar.gz

1-2.解压安装包

[root@10 ~]# tar -C /usr/local -zxvf go1.5.3.linux-amd64.tar.gz

安装到/usr/local

1-3.定义 PATH 环境变量

 [root@10 ~]# vim /etc/profile

添加export PATH=$PATH:/usr/local/go/bin

 [root@10 ~]# source /etc/profile

1-4.校验

[root@10 ~]# go

出现参数信息,则安装成功

1-5.GOPATH 环境变量

The GOPATH environment variable specifies the location of your workspace.
Note that this must not be the same path as your Go installation.

 [root@10 ~]# mkdir /data1/gowork

 [root@10 ~]# vim /etc/profile

添加export GOPATH=/data1/gowork

 [root@10 ~]# source /ect/profile

2.gor 工具

2-1.编译 gor

[root@10 ~]#go get github.com/buger/gor

[root@10 ~]#cd $GOPATH/src/github.com/buger/gor

[root@10 gor]#go build

在当前目录生成 gor 可执行命令

 [root@10 gor]# ./gor
Version: 
2016/01/24 11:01:01 Required at least 1 input and 1 output

将/data1/gowork/bin/gor 命令建立软链:

ln -s /data1/gowork/bin/gor /usr/bin/gor

2-2.工具部分使用方式

2-2-1.实时引流:

执行机器:10.13.1.139

[root@10 goload]# gor --input-raw :20001 --output-http 10.75.0.101:8077 

将 10.13.1.139:20001 的请求,同时打到 10.75.0.101:8077

2-2-2.保存请求到文件并回放

保存请求到文件

[root@10 goload]# gor --input-raw :20001 --output-file requests.gor

回放请求

[root@10 goload]# gor --input-file requests.gor --output-http "10.75.0.101:8077"

2-2-3.Load testing

只支持 input-file 文件, 如下用例:10x speed

 [root@10 goload]# gor --input-file "requests.gor|1000%" --output-http "10.75.0.101:8077"  
Version: 
2016/01/24 16:07:48 FileInput: end of file

wiki:https://github.com/buger/gor

3.另一种引流方式:tcpcopy

  1. 机器资源多, gor 只需在生产环境机器使用,“tcpcopy 运行需要 intercept 的支持,tcpcopy 负责抓包和发包工作,而 intercept 负责截获应答包”,需要单独一条机器作为 intercept, assistant server(运行 intercept 的机器)原则上必须要和测试服务器(test server)在同一个网段。
  2. 配置较复杂,gor 只需一条命令就能解决问题,tcpcopy 由 3 部分组成,(1).online server(2).Test Server(3).Assistant Server

    实例 (tcpcopy1.0 系列使用方法):
    在线 adserver 有 2 台,主要供 nginx 调用,所以客户端 IP 地址来自于 nginx 所在机器的 IP 地址,均为同一网段的 IP 地址。
    我们假设在线 adserver 机器为 10.100.10.1,10.100.10.2,nginx 所在的机器 ip 地址为:10.100.10.11,10.100.10.12,10.100.10.13,
    测试服务器有 10.100.10.31,10.100.10.32(辅助服务器)
    其中,10.100.10.31 运行着类似在线 adserver 的应用,端口为 11511,而在线应用端口是 11311
    我们在 10.100.10.31 上面添加如下路由:
    route add -host 10.100.10.11 gw 10.100.10.32
    route add -host 10.100.10.12 gw 10.100.10.32
    route add -host 10.100.10.13 gw 10.100.10.32
    这里的意思就是说,在测试服务器 10.100.10.31 返回给客户端 10.100.10.11~13 的响应走默认网关 10.100.10.32,但 10.100.10.32 机器其实并没有开启路由模式,所以这些响应包到了 10.100.10.32 机器后,会在 ip 层被 drop 掉,留给我们的机会就是可以在 10.100.10.32 的数据链路层抓到这些响应包。
    我们在 10.100.10.32 机器(辅助服务器)上面运行 intercept,用来捕获响应包,命令如下:
    执行 intercept 命令(需要 root 权限):
    ./intercept -i eth0 -F 'tcp and src port 11511' -d
    我们在在线机器上面运行 tcpcopy(root 权限):
    ./tcpcopy -x 11311-10.100.10.31:11511 -s 10.100.10.32 -d
    这里 tcpcopy 的含义是复制在线 11311 端口的数据包到 10.100.10.31 上面的 11511 端口中去,-s 指定运行 intercept 所在机器的 ip 地址。

  3. gor 现只支持根据离线文件(--input-file),加速请求;tcpcopy 支持在线流量放大(-n)。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 15 条回复 时间 点赞

能举个 线上的案例吗?

将 10.13.1.139:20001 的请求,同时打到 10.75.0.101:8077

这个会影响 10.13.1.139 的性能吗?

#1 楼 @lihuazhang
1.是否会影响 10.13.1.139 的性能?
会对 10.13.1.139 机器性能有影响,gor 推荐使用单独的机器作为 Replay server:

# Run on servers where you want to catch traffic. You can run it on each web machine.
sudo gor --input-raw :80 --output-tcp replay.local:28020
# Replay server (replay.local).
gor --input-tcp replay.local:28020 --output-http http://staging.com

如果你的机器性能较高(cpu 资源配置高等)可以使用 gor 单实例 replay(上述 2-2-1),通常这种选取都是集群中单台机器,不影响整个服务。

2.线上案例?
案例不方便透露,思路可以分享下:
1).实时流量 replay,这种方式可以作为新系统上线前,用线上数据持续测试该系统,降低回滚几率,一般上线流程都是 1.测试环境功能测试->2.预览环境功能测试(线上机器摘取 * 台,线上无读写)->3.线上环境功能测试, 功能测试场景是否能完全覆盖全,是否能在测试环境下用线上真实数据发现系统的缺陷,通过 warn.log, error.log 观察异常堆栈,定位代码问题。

2).load test, 通常压测都是测试人员自己构造场景脚本,而这个场景是否能覆盖全线上所有的场景,用线上真实数据压测更有说服力,当然这种压测收集数据需要成本,不像某些工具(LR, nGrinder)本身集成了收集数据。

请问线上用户数据的安全性 (密码,信用卡号等) 怎么去保证呢?

有些局限性啊:
(1) 只支持 Linux
(2) Due to the fact that Gor can't guarantee interception of all packets, for large payloads > 200kb there is chance of missing some packets and corrupting body.

我看到有 tcpReplay 是实验性质地支持 Windows, 但跑起来也很麻烦

#3 楼 @ansonwoo

怎么去保证用户数据的安全性?

这种内部测试,是能获取到部分敏感信息的,但是系统安全性高的话,不能仅靠部分信息就能继续操作的,比如手机验证码验证等,还是靠职业操守。

Gor 支持 SSL

Can i use Gor to intercept SSL traffic?

Basic idea is that SSL was made to protect itself from traffic interception. There 2 options: 1. Move SSL handling to proxy like Nginx or Amazon ELB. And allow Gor to listen on upstreams. 2. Use --input-http so you can duplicate request payload directly from your app to Gor, but it will require your app modifications.

More can be find here: https://github.com/buger/gor/issues/85

对于加密数据有 2 种方式:1. Move SSL handling to proxy, 2. Use --input-http;

引流只是验证新系统整体的正确性,不影响线上系统,是互相隔离的。

如果只针对某个点做性能测试,可以 LR,nGrinder,JMeter 做单个点压测。

#4 楼 @ansonwoo 1.现在大部分公司服务都是部署在 linux 上,至少我所在公司都是部署在 linux 上; 2.使用--input-http

#7 楼 @neven7 这种流量回放适合性能测试,有没有可能用来做自动化回归测试呢?

胡刚 #11 · 2016年02月22日 Author

#8 楼 @lihuazhang 可是可以,但成本较大,这种比较适合依赖资源较少的系统;(1)学习代码成本,这种流量回放可以作为自动化回归测试的一种补充,验证系统是否有错,而这种方式你不知道预期结果,需要通过 warn.log 和 error.log 查看代码中异常栈,这要求测试人员熟悉开发的代码;(2)资源成本,要求被测系统和线上系统是隔离的(底层资源隔离等),回放被测系统不能影响到线上系统,你必须搭建与线上一致的测试资源。其实在我们的日常上线中,预览测试通过时,运维会放量预览机,线上的请求打到预览机,这时有上线的开发会观察预览机的 warn.log 和 error,做的都很类似。

gor 之前搞过。可以利用 middleware 搞定 token 这类动态数据。
但抓取流量时会对线上业务性能有些影响;
感觉更适合验证服务器迁移

我想问下,你在引流的时候会出现这样的 log 么?

[DEBUG][PID 2963][1462464251310765636][3534.317016ms] [HTTPClient] Connecting: http://www.verycd.com
[DEBUG][PID 2963][1462464251310821301][0.055665ms] [HTTP] Disconnected:  http://www.verycd.com

就我都是 http,然后就是连接不上。。。。

#2 楼 @neven7
你好,想讨教 2 个问题:
1、你说 “不像某些工具(LR, nGrinder)本身集成了收集数据”,想问问看,nGrinder 的数据收集功能在哪呢?一直都不知道有。
2、对于流量回放中的 http 长链接的请求,比如一个查询请求需要关联到该用户 5 分钟前的一次成功登录,可能这 2 个请求(登录、查询)被分配到不同压测机或线程上去的话就会因为登录状态不同而查询不正确,如何在茫茫流量中,去关联其中有依赖性的请求呢,有什么好的办法吗?
谢谢!

胡刚 #13 · 2016年11月20日 Author

#12 楼 @johnson 1.之前整理过一系列 ngrinder 源码分析的文章,请参考:http://blog.csdn.net/neven7/article/details/50835088; 2.我描述下你的问题:要压测连串的 2 个接口一个登录、查询;登录的时间影响查询接口,压测情况下是登入接口是随机的,会影响到查询接口;2-1)解决:你压测过过程中每隔 5 分钟回放登录的请求;查询接口就可以了; 2-2)解决:你可以叫开发 mock 掉查询用户的登入时间,你直接回放查询接口,对查询接口压测就行了

你好, tcpcopy 和 gor 是否支持 https 的请求复制

有遇到过文件上传下载,gor 没记录的情况吗?怎么解决的

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册