流量回放工具

作用


在评估某个服务可用性时,一种常见方式是采用一些压测工具(如ab/hey/jmeter/siege/wrk/locust等)压测某几个核心接口,一般看达到某个TPS/QPS时,CPU/内存等资源的水位;或者固定资源的阈值,看最高能达到的TPS/QPS。

但这样有一个问题: 对于线上服务,真实用户的请求是复杂的,如请求的接口顺序,带的参数。这很可能会影响服务真实的可用性。(如某个接口A请求方法B,在B中有一段逻辑,带的参数恰好满足时,会触发清空全部缓存,加锁等,仅仅压测某几个核心接口,对于服务稳定性的评估,是不够全面的)。

自然而然的想法是希望能mock用户真实的请求,最好还可以同比例放大。


社区已经有不少这样的流量回放工具,比较知名的有 goreplay[1],以及滴滴的sharingan[2]。 从star数量和活跃程度上说,前者可以说稳压后者。下面以goreplay为例,演示该工具的使用。

goreplay不仅支持流量的实时放大,同时也可以缩小,进行频控等。同时也可以把请求写到到文件,进行非实时的回放和分析。

alt

(图片来自 官方仓库readme.md[3])

注: 虽然此工具用Go开发,但无需与线上项目做集成,而是作为工具,独立于用户项目之外。故而不关心用户的技术栈,Java,Python,Rust等开发的web服务,同样可用此做流量回放。




使用


官方已经有编译好的二进制包(名为gor),无需使用者再通过源码编译。可点击 https://github.com/buger/goreplay/releases 根据相应系统下载所需版本。

另外,gor需要依赖libpcap,如果没有需要安装。不同系统的安装方式有所差异。

libpcap(Packet Capture Library)是一个用于网络数据包捕获的库。其提供了一组函数和工具,用于在计算机网络上捕获数据包并进行分析。libpcap 可以从网络接口(例如以太网、Wi-Fi)上捕获数据包,并提供了对数据包的访问、过滤、存储和分析的功能。

常用于网络监控、网络安全、网络调试和网络分析等领域。一些常见的用途包括:

  1. 网络流量分析:通过捕获网络数据包,分析网络流量的来源、目的、协议、负载等信息,以便进行网络性能优化、故障排除和安全分析。

  2. 网络安全和入侵检测:通过捕获网络数据包,检测和分析潜在的网络攻击、恶意行为和异常流量,以保护网络的安全。

  3. 网络协议开发和测试:用于开发和测试网络协议的实现,验证协议的正确性和性能。

  4. 网络流量重放和模拟:通过捕获的数据包,重放网络流量,模拟真实的网络环境,用于测试和评估网络应用、设备和系统的性能和稳定性。


以下是用 Rust Actix Web框架开发的一个简单Web服务,定义两个接口,模拟分别处理不同业务。

use actix_web::{get, web, App, HttpServer, Responder};

#[get("/hello/{name}")]
async fn greet(name: web::Path<String>) -> impl Responder {
    println!("这是接口a,开始进行各种复杂逻辑");
    format!("Hello {name}!")
}

#[get("/clear/{name}")]
async fn clear(name: web::Path<String>) -> impl Responder {
    println!("这是接口b,清空全部缓存");
    format!("Clear {name}!")
}


#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
        .service(greet)
        .service(clear)
    })
    .bind(("127.0.0.1"8080))?
    .run()
    .await
}

Cargo.toml为:

[package]
name = "web-active"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "4.4.0"

执行cargo run

请求 http://127.0.0.1:8080/hello/zhangsan

alt
alt

请求 http://127.0.0.1:8080/clear/cache1

alt
alt

执行 sudo gor --input-raw :8080 --output-file=my-service-request.gor

请求三次 http://127.0.0.1:8080/hello/zhangsan,两次http://127.0.0.1:8080/clear/cache1

alt
alt

停止gor,发现当前目录下多了一个my-service-request_0.gor,这就是gor借助libpcap所录制的请求文件。

alt

文件内容如下,cat my-service-request_0.gor:

1 f9e91f907f000001b4a53843 1697625311455924000 0
GET /hello/zhangsan HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ca;q=0.7


🐵🙈🙉
1 f9f71f907f00000127af03b3 1697625311456071000 0
GET /hello/zhangsan HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ca;q=0.7


🐵🙈🙉
1 f9f71f907f00000127af0437 1697625312448706000 0
GET /hello/zhangsan HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ca;q=0.7


🐵🙈🙉
1 f9f71f907f00000127af04bb 1697625315970845000 0
GET /clear/cache1 HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ca;q=0.7


🐵🙈🙉
1 f9f71f907f00000127af053d 1697625317366548000 0
GET /clear/cache1 HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ca;q=0.7


🐵🙈🙉

停止监听8080端口的rust服务,新起一个监听9999端口的服务 (模拟用于承接流量回放请求的服务,一般可能是低峰期的线上服务地址,或者是预发地址/压测地址)

然后执行 gor --input-file my-service-request_0.gor --output-http="http://127.0.0.1:9999"

alt

这是通过文件的方式,延后回放流量。goreplay也支持实时流量回放:

sudo gor --input-raw :8080 --output-http="http://可以是一个公网ip:相应端口"

如果output后面的参数改为stdout,即 sudo gor --input-raw :8080 --output-stdout 则为实时将请求输出到终端


另外,还可以使用流量放大功能进行压测,将流量转发到多个节点,基于Header或Url参数,或基于GET/POST等进行限制等。

更多可选参数及用法可参考官方文档[4]

参考资料

[1]

goreplay: https://github.com/buger/goreplay

[2]

sharingan: https://github.com/didi/sharingan

[3]

官方仓库readme.md: https://github.com/buger/goreplay

[4]

官方文档: https://github.com/buger/goreplay/wiki/

本文由 mdnice 多平台发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
流量回放工具goreplay是一个开源的工具,它可以用来记录和回放HTTP/HTTPS流量。如果你想要进行压测并统计结果,可以对goreplay进行一些改造。 首先,你需要安装goreplay并启动它来进行流量录制和回放。然后,你可以使用一个脚本来发送请求并记录响应时间。以下是一个示例脚本: ```bash #!/bin/bash while read line; do url=$(echo $line | cut -d ' ' -f 2) time=$(curl -o /dev/null -s -w %{time_total} $url) echo $time >> response_times.log done < urls.txt ``` 这个脚本从一个名为urls.txt的文件中读取URL,并使用curl发送请求并记录响应时间。响应时间被写入response_times.log文件中。 一旦你有了响应时间的记录,你可以使用其他工具来进行统计和分析。例如,你可以使用awk命令来计算平均响应时间: ```bash awk '{sum+=$1} END {print "Average response time: " sum/NR "s"}' response_times.log ``` 这个命令将response_times.log文件中的所有响应时间相加,然后除以记录数来计算平均响应时间。 你也可以使用其他工具,如Grafana、Prometheus和InfluxDB等来可视化和分析数据。例如,你可以使用Grafana来创建一个响应时间的实时监控面板。 改造goreplay支持压测统计是可行的,但需要一定的技术水平和时间投入。你需要了解golang和HTTP/HTTPS协议,并对goreplay的代码进行修改。如果你需要更加专业的支持,可以考虑向goreplay的开发团队寻求帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值