首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用云压测回放 GoReplay 录制的请求

使用云压测回放 GoReplay 录制的请求

作者头像
腾讯云可观测平台
修改于 2024-12-16 07:27:09
修改于 2024-12-16 07:27:09
47807
代码可运行
举报
运行总次数:7
代码可运行

柯开

腾讯云高级工程师,腾讯云压测 OTeam 发起人,目前主要负责腾讯云可观测系统的开发与设计。

GoReplay 简介

GoReplay 是一个开源的流量录制回放工具。主要用于捕获实时流量并将其复制到测试环境中。这样做可以帮助开发者和测试人员在不影响实际用户的情况下,对软件进行压力测试和问题排查。GoReplay 是用 Go 语言编写的,因此它非常高效且易于部署。

GoReplay 的工作原理是监听服务器的网络接口,捕获进出的 HTTP 流量,并选择性地重新发送这些请求到另一个服务器。这对于模拟真实用户行为、测试服务器的负载能力、查找并修复 bug、以及监控服务的稳定性都非常有用。

由于 GoReplay 本身并不提供一个分布式运行方案,只能在单机上运行。在流量录制完成后,受限于单机资源瓶颈,我们很难大规模的重放录制的流量,无法有效的模拟真实用户流量的压测行为以及极限测试。同时也缺乏压测时的监控图表,无法观测系统实时状况:比如请求成功率,响应延时,QPS 等。

腾讯云云压测是一款分布式性能测试服务,支持百万级别的高并发压测,可模拟海量用户的真实业务场景。因此我们可以引入云压测,使用云压测来回放 GoReplay 录制的真实流量。通过云压测我们可以在非常多的节点上回放用户流量并产生实时报告,帮助我们判断系统实时状况,找出性能瓶颈。

本文将通过一个实例演示:使用 GoReplay 录制网关接收到的请求,将请求各个字段保存成 CSV 文件。在云压测中,通过上传CSV 参数文件,指定期望的并发数,分布式回放请求到用户指定的地址。

常用 GoReplay 使用场景

  • 性能测试:通过复制生产环境的流量到测试环境,可以在不影响真实用户的情况下对应用程序进行压力测试和性能评估。
  • 故障排除和调试:当生产环境出现问题时,可以捕获相关的流量并在一个隔离的环境中重放,以便开发人员可以安全地调试问题而不会影响实际服务。
  • 回归测试:在发布新版本之前,可以使用 GoReplay 捕获的流量来验证更改是否会引入新的错误或性能问题。
  • A/B 测试:可以将流量同时发送到两个服务版本,比较它们的表现,以便做出数据驱动的决策。
  • 流量回放测试:通过在回放时候,加大回放请求的倍数,模拟高流量情况,可以帮助确定在不同负载下所需的资源量。

GoRepaly 流量录制原理

如果你用过 tcpdump, 你会发现 tcpdump 跟 GoReplay 使用场景很接近,都是监听网络流量,再做后续处理。

tcpdump 一般被用来捕获网络流量,并打印出来,用来排查疑难的网络问题。

比如监听目标端口8080的网络包,并写入到 mypackets.pcap 文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo tcpdump dest port 8080 -w mypackets.pcap

GoReplay 流量录制也是监听指定端口流量,录制成 gor 文件(或者发送到其他目的端),方便后续回放:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo gor --input-raw :8080 --output-file requests.gor

tcpdump 和 GoReplay 都是依赖 BPF 组件来进行网络流量捕获。那么 BPF 是什么,它又是如何工作的呢?

BPF 全名为 BSD Packet Filter, 被广泛应用于网络监测。BPF 运行在内核态,根据用户定义的规则直接过滤收到的包,拷贝到用户态程序可以拿到的 buffer 中。

BPF 基本结构图如下:

BPF 主要包含两个组件:

  • the network tap:

tap 主要负责从指定的网络设备中拷贝数据包,并发送到监听的应用程序。由于每个数据包间隔时间很短,且都要经过 filter 过滤。tap 不可能对每个数据包都调用一次 read 系统,那样效率很低。tap 解决方案是一次读取多个数据包数据,并包一层 header, 用来区分各个数据包直接的边界,通过这种方式来加快数据处理效率。

  • the packet filter:

filter 主要就是用来过滤包。BPF 会根据不同的 filter 就地进行过滤,而不会拷贝到内核其他 buffer 中,整体处理相当高效。

我们使用的 GoReplay 和 tcpdump 都是基于 BPF 技术。

值得一提的是,Linux 内核现在默认使用 EBPF, EBPF 是 BPF 的增强版,提供更多的功能和灵活性。我们一般叫 BPF 称做 cBPF(classic bpf), 以与 EBPF 做区分。EBPF 可参考:https://ebpf.io/what-is-ebpf/

EBPF 完全向前兼容 BPF,用户无需关注底层实现上的变化。Linux 通过这种方式来确保 tcpdump, GoReplay 这些程序在新的 Linux 系统上也能正常运行。

对于 GoReplay 来说,在基于 EBPF 实现的系统上监听网络流量后台流程如下:

  1. filter 编译:GoReplay 使用编译器将 filter 表达式转换成 BPF bytecode。这些 bytecode 是一系列指令告知内核如何将包发送给 GoReplay;
  2. cBPF 翻译到 EBPF: 当 cBPF bytecode 加载进内核时,内核自动将 cBPF bytecode 转化成 EBPF bytecode;
  3. 执行:EBPF bytecode 将在 Verifier 层进行安全性校验, 在 JIT Compiler 进一步编译成机器码,当数据穿过网络堆栈时,被内核执行:过滤数据包并转发到 GoReplay。

使用云压测录制回放用户网关

本文以录制回放 Nginx 网关为例,其他所有类型的网关都可以按照相同的方式来录制请求,再使用云压测来回放用户请求。

1.环境准备

整个实验需要以下组件:

  1. Nginx 网关:Nginx 网关上有源源不断的用户请求,我们需要在 Nginx 网关录制下这些请求;
  2. GoReplay: 请求录制回放工具;
  3. CSV 生成服务:接收 HTTP 请求,将接收到的请求各个字段写入 CSV 文件中;
  4. 云压测:基于用户上传的 CSV 文件,回放用户录制的所有请求。

安装 GoReplay 到你的网关所在机器上

如果网关所在机器是 Linux 或 macOS,可以使用以下命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 从官方GitHub仓库下载最新的二进制文件
curl -L https://github.com/buger/goreplay/releases/download/1.3.3/gor_1.3.3_x64.tar.gz | tar xz

# 将二进制文件移动到你的PATH目录中,例如/usr/local/bin
mv gor /usr/local/bin/

确保替换上的URL 中的版本号为最新的版本,仓库地址:https://github.com/buger/goreplay。

2.实验流程

2.1 将 Nginx 上的请求录制成 Gor 文件

本节参与组件(其他组件仅做完整场景展示):

  1. Nginx 网关:Nginx 网关上有源源不断的用户请求,我们需要在 Nginx 网关录制下这些请求;
  2. GoReplay: 请求录制工具。

整体架构图如下:

要开始录制流量,你需要在网关所在服务器上运行 GoReplay。以下是一个基本的命令示例,它会监听网关上的80端口,并将捕获的流量保存到一个文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo gor --input-raw :80 --output-file requests.gor

这个命令会捕获所有通过端口80的流量,并将其保存到当前目录下的 requests.gor 文件中。请注意,你可能需要 sudo 权限来监听80端口。

2.2 将 Gor 文件转换成 CSV 参数文件

本节参与组件:

  1. GoReplay: 请求录制工具。本节使用 GoReplay 回放Gor 文件中记录的请求到 CSV 生成服务;
  2. CSV 生成服务:接收 HTTP 请求,将接收到的请求各个字段写入 CSV 文件中。

整体架构如下

在 CSV 文件中我们记录下请求各个字段, 比如 scheme, host, uri, method, base64Body。

下面是一个简单 CSV 文件样例:

scheme

host

uri

method

jsonHeaders

base64Body

http

mockhttpbin.pts.svc.cluster.local

/get?page=1

get

{"name":"kk"}

http

mockhttpbin.pts.svc.cluster.local

/post

post

{"Hello": 'world',}

dGhpcyBpcyBnb29kCg==

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scheme,host,uri,method,jsonHeaders,base64Body
http,mockhttpbin.pts.svc.cluster.local,/get?page=1,get,{"name":"kk"},
http,mockhttpbin.pts.svc.cluster.local,/post,post,{"hello":"world"},dGhpcyBpcyBnb29kCg==

为什么使用 base64Body,而不是直接记录 body呢?

由于有些请求的 body 发送的二进制文件,直接写入 CSV 文件会展示成乱码。写成 base64后,可以方便后续转换成原来的结构体。

a. CSV 生成服务代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
  "encoding/base64"
  "encoding/csv"
  "encoding/json"
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
  "os"
)

func main() {
  http.HandleFunc("/", requestHandler) // 设置处理函数
  log.Println("Server starting on port 8080...")
  log.Fatal(http.ListenAndServe(":8080", nil))
}

func requestHandler(w http.ResponseWriter, r *http.Request) {
  // 获取请求信息
  scheme := "http" // 默认为http,因为Go的http包不支持直接获取scheme
  if r.TLS != nil {
    scheme = "https"
  }
  host := r.Host
  uri := r.RequestURI
  method := r.Method

  // 将headers转换为JSON格式
  headersJson, err := json.Marshal(r.Header)
  if err != nil {
    http.Error(w, "Error converting headers to JSON", http.StatusInternalServerError)
    return
  }

  // 读取请求体
  body, err := ioutil.ReadAll(r.Body)
  if err != nil {
    http.Error(w, "Error reading request body", http.StatusInternalServerError)
    return
  }
  defer r.Body.Close()

  // Base64编码请求体
  base64Body := base64.StdEncoding.EncodeToString(body)

  // 写入CSV文件
  record := []string{scheme, host, uri, method, string(headersJson), base64Body}
  err = writeToCSV(record)
  if err != nil {
    http.Error(w, "Error writing to CSV", http.StatusInternalServerError)
    return
  }

  // 发送响应
  fmt.Fprintf(w, "Request logged")
}

func writeToCSV(record []string) error {
  file, err := os.OpenFile("requests.csv", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  if err != nil {
    return err
  }
  defer file.Close()

  writer := csv.NewWriter(file)
  defer writer.Flush()

  return writer.Write(record)
}

b. 编译并运行 CSV 生成服务

将上述文件保存成 main.go文件,直接运行代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
go run main.go

c. 回放流量到 CSV 生成服务上, 用来生成 CSV 文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gor --input-file requests.gor --output-http "http://csv-server-address:8080" --http-original-host true

这个命令会读取 requests.gor 文件中的流量,并将其回放到 CSV 生成服务上, CSV 生成服务默认会将接收到的请求写成 requests.csv 文件里;且生成的流量 host 为请求原本的 host 而非 CSV 服务的地址。

2.3 在云压测上使用 CSV 参数文件回放请求

云压测支持用户上传 CSV 文件作为参数文件。您可以动态引用其中的测试数据,供脚本里的变量使用。这样,当施压机并发执行这段代码,每条请求能动态、逐行获取 CSV 里的每行数据,作为请求参数使用。

a. 登录腾讯云云压测,云压测对于首次使用的用户提供一个免费的压测资源包。

b. 测试场景-> 新建场景 → 创建脚本模式

云压测脚本模式支持原生 JavaScript ES2015(ES6)+ 语法,并提供额外函数,帮助您在脚本模式下,快速编排压测场景。

您可在控制台的在线编辑器里,用 JavaScript 代码描述您的压测场景所需的请求编排、变量定义、结果断言、通用函数等逻辑。

c. 指定压测并发数,从上海,广州两个地域分布式发起压测。

d. 上传之前录制的 CSV 文件,作为参数文件。

e. 编写压测脚本,施压机每次执行压测脚本时候,读取 CSV 文件中下一行,利用CSV 文件中记录的字段重新构造出原始请求。

压测脚本如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Send a http get request
import http from 'pts/http';
import { check, sleep } from 'pts';
import util from 'pts/util';
import dataset from 'pts/dataset';


export default function () {
  // 读取csv文件各个字段
  var method = dataset.get("method")
  var scheme = dataset.get("scheme")
  var host = dataset.get("host")
  var uri = dataset.get("uri")
  var jsonHeaders = dataset.get("jsonHeaders")
  var base64Body = dataset.get("base64Body")

  var headers = JSON.parse(jsonHeaders)
  var body = util.base64Decoding(base64Body, "std", "b")

  // 构造请求
  var req = {
    method: method,
    url: scheme + "://" + host + uri,
    headers: headers,
    body: body
  }

  // 发送请求
  var resp = http.do(req)

  // simple get request
  console.log(resp.body);
  check('status is 200', () => resp.statusCode === 200, resp);
  // sleep 1 second
  sleep(1);
}

f. 保存并运行,即可运行压测脚本,回放流量。查看压测报告及请求采样,观察请求是否符合预期。

请求采样:

总结

通过以上案例,我们展示了如何使用 GoReplay 录制网关流量,并使用云压测脚本模式重新构造用户录制的请求,分布式的回放录制的流量。在压测过程中我们还能产生实时报表,帮助监测被压测服务 QPS,响应时间,错误率等,从而对被压测服务整体健康状况有一个直观的掌控。

云压测除开提供上述脚本模式外,还提供其他模式,包括:

简单模式:以白屏化的方式使用我们交互式 UI 组合 GET,POST,PUT,PATCH,DELETE 请求。

JMeter 模式:使用原生的 JMeter JMX 文件进行压测,用户只需设置指定线程数,即可分布式在多台机器上同时发起压测。

若您有任何压测需求,欢迎试用腾讯云云压测,体验一个灵活、好用、且在不断迭代中的全新压测平台。

联系我们

如有任何疑问,欢迎扫码进入官方交流群~

关于腾讯云可观测平台

腾讯云可观测平台(Tencent Cloud Observability Platform,TCOP)基于指标、链路、日志、事件的全类型监控数据,结合强大的可视化和告警能力,为您提供一体化监控解决方案。满足您全链路、端到端的统一监控诉求,提高运维排障效率,为业务的健康和稳定保驾护航。功能模块有:

  • Prometheus 监控:开箱即用的 Prometheus 托管服务;
  • 应用性能监控 APM:支持无侵入式探针,零配置获得开箱即用的应用观测能力;
  • 云拨测 CAT:利用分布于全球的监测网络,提供模拟终端用户体验的拨测服务;
  • 前端性能监控 RUM:Web、小程序等大前端领域的页面质量和性能监测;
  • Grafana 可视化服务:提供免运维、免搭建的 Grafana 托管服务;
  • 云压测 PTS:模拟海量用户的真实业务场景,全方位验证系统可用性和稳定性;
  • ......等等
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云可观测 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
机器学习统计概率分布全面总结(Python)
在平时的科研中,我们经常使用统计概率的相关知识来帮助我们进行城市研究。因此,掌握一定的统计概率相关知识非常有必要。
算法进阶
2023/12/26
6390
机器学习统计概率分布全面总结(Python)
深度好文 | 探索 Scipy 与统计分析基础
云朵君推荐 本文部分内容仅展示部分核心代码,本文提供含完整代码的完整PDF版本下载,获取方式:关注公众号 「数据STUDIO」并回复【210512】获取。若你对代码不感兴趣,直接略过,不影响阅读。
数据STUDIO
2021/06/24
3.1K0
【编写环境二】python库scipy.stats各种分布函数生成、以及随机数生成【泊松分布、正态分布等】
norm.rvs通过loc和scale参数可以指定随机变量的偏移和缩放参数,这里对应的是正态分布的期望和标准差。size得到随机数数组的形状参数。(也可以使用np.random.normal(loc=0.0, scale=1.0, size=None))
汀丶人工智能
2022/12/21
1.9K0
【编写环境二】python库scipy.stats各种分布函数生成、以及随机数生成【泊松分布、正态分布等】
python中Copula在多元联合分布建模可视化2实例合集|附数据代码
Copula是一个用于描述多个随机变量之间相关性的函数,它将这些变量的联合分布与其边缘分布连接起来。Copula函数由Sklar定理所定义,该定理指出,对于N个随机变量的联合分布,可以将其分解为这N个变量各自的边缘分布和一个Copula函数。
拓端
2024/12/03
2760
python中Copula在多元联合分布建模可视化2实例合集|附数据代码
机器学习数学基础:常见分布与假设检验
所谓机器学习和深度学习, 背后的逻辑都是数学, 所以数学基础在这个领域非常关键, 而统计学又是重中之重, 机器学习从某种意义上来说就是一种统计学习。
Datawhale
2020/07/09
3.4K0
机器学习数学基础:常见分布与假设检验
常见概率分布
在一次实验中,事件A出现的概率为 ,不出现的概率为 ,若用 记事件A出现的次数,则 仅取值0或1,相应的概率分布为
用户3577892
2020/06/10
7830
概率论04 随机变量
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
Vamei
2018/09/25
9990
概率论04 随机变量
数据挖掘学习小组之(概率分布)
随机变量(random variable)表示随机试验各种结果的实值单值函数。随机事件不论与数量是否直接有关,都可以数量化,即都能用数量化的方式表达!
数据处理与分析
2019/08/05
7570
概率论04 随机变量
我们了解了“样本空间”,“事件”,“概率”。样本空间中包含了一次实验所有可能的结果,事件是样本空间的一个子集,每个事件可以有一个发生的概率。概率是集合的一个“测度”。 这一讲,我们将讨论随机变量。随机变量(random variable)的本质是一个函数,是从样本空间的子集到实数的映射,将事件转换成一个数值。根据样本空间中的元素不同(即不同的实验结果),随机变量的值也将随机产生。可以说,随机变量是“数值化”的实验结果。在现实生活中,实验结果可以是很“叙述性”,比如“男孩”,“女孩”。在数学家眼里,这些文字化
Vamei
2018/01/18
9470
概率论04 随机变量
连载 | 概率论与数理统计(3) – 一维离散型随机变量及其Python实现
上一小节对随机变量做了一个概述,这一节主要记录一维离散型随机变量以及关于它们的一些性质。对于概率论与数理统计方面的计算及可视化,主要的Python包有scipy, numpy和matplotlib等。
小莹莹
2018/07/24
1.3K0
连载 | 概率论与数理统计(3) – 一维离散型随机变量及其Python实现
用Python结合统计学知识进行数据探索分析
# 导入相关模块import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns %matplotlib inline %config InlineBackend.figure_format = 'retina'
IT阅读排行榜
2018/08/17
1.2K0
用Python结合统计学知识进行数据探索分析
在统计学中概率分布中的概率密度函数PDF,概率质量PMF,累积分布CDF
一. 概念解释 PDF:概率密度函数(probability density function), 在数学中,连续型随机变量的概率密度函数(在不至于混淆时可以简称为密度函数)是一个描述这个随机变量的输出值,在某个确定的取值点附近的可能性的函数。 PMF : 概率质量函数(probability mass function), 在概率论中,概率质量函数是离散随机变量在各特定取值上的概率。 CDF : 累积分布函数 (cumulative distribution function),又叫分布函数,是概率密度函
学到老
2018/03/19
3.3K0
概率和分布
概率空间:sample space,events space和probability function
esse LL
2024/08/07
1290
SciPy从入门到放弃
SciPy是一种以NumPy为基础,用于数学、工程及许多其他的科学任务的科学计算包,其使用的基本数据结构是由NumPy模块提供的多维数组,因此Numpy和SciPy协同使用可以更加高效地解决问题。SciPy很适合用于十分依赖数学和数值运算的问题,其内部的模块包括优化模块、线性代数模块、统计模块、傅里叶变化模块、积分模块、信号处理模块、图像处理模块、稀疏矩阵模块、插值模块等。
愷龍
2024/08/15
1740
SciPy从入门到放弃
Python实现 8 个概率分布公式及可视化
概率和统计知识是数据科学和机器学习的核心; 我们需要统计和概率知识来有效地收集、审查、分析数据。
数据STUDIO
2022/05/24
1.3K0
Python实现 8 个概率分布公式及可视化
【机器学习】从流动到恒常,无穷中归一:积分的数学诗意
在机器学习的学习旅程中,微积分不仅仅是理论的支撑,更是实际应用的关键工具。上一篇文章中,我们探讨了极限与连续性以及导数的概念与应用,特别是在梯度下降法中的应用。本篇文章将继续深入,重点讲解积分的概念与计算,以及它在机器学习中的实际应用。
半截诗
2025/01/09
1650
【机器学习】从流动到恒常,无穷中归一:积分的数学诗意
Python NumPy自定义随机分布生成器
随机数生成是数据分析、模拟和机器学习中的重要组成部分。NumPy 提供了强大的随机数生成工具,涵盖了多种常见分布(如正态分布、均匀分布等)。在实际应用中,经常需要根据特定需求创建自定义的随机分布生成器。
sergiojune
2025/01/15
2220
Python NumPy自定义随机分布生成器
​常见的8个概率分布公式和可视化
来源:Deephub Imba本文约2800字,建议阅读8分钟本文我们将介绍一些常见的分布并通过Python 代码进行可视化以直观地显示它们。 概率和统计知识是数据科学和机器学习的核心;我们需要统计和概率知识来有效地收集、审查、分析数据。 现实世界中有几个现象实例被认为是统计性质的(即天气数据、销售数据、财务数据等)。这意味着在某些情况下,我们已经能够开发出方法来帮助我们通过可以描述数据特征的数学函数来模拟自然。 “概率分布是一个数学函数,它给出了实验中不同可能结果的发生概率。” 了解数据的分布有助于更好
数据派THU
2022/04/29
1.1K0
​常见的8个概率分布公式和可视化
单变量图的类型与直方图绘图基础
单变量图(chart for one variable)是指使用数据组的一个变量进行相应图的绘制。想要可视化这个变量,就需要根据不同的数据变量类型绘制图。数据变量分为连续变量(continuous variable)和离散型变量(discrete variable)。
timerring
2023/10/13
7900
单变量图的类型与直方图绘图基础
概率论06 连续分布
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
Vamei
2018/09/25
8250
概率论06 连续分布
推荐阅读
相关推荐
机器学习统计概率分布全面总结(Python)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档