1、goreplay流量回放
- 目的
在实际项目中,会有大量的回归测试工作,通常会使用自动化代码的手段来实现回归,但是对于一个庞大的系统来说,通过自动化脚本的方式来实现回归测试,又显得很费时费力。并且如果有定期将线上数据同步到测试环境的需求的话,流量回放就显得很必要了。当然,流量回放并不能替代自动化,对于存在上下文关联的接口,流量回放的处理上就显得很复杂。
- 流量回放
其实流量回放主要是对某个端口的流量进行转发和存储,这边用的是goreplay,mitmproxy也可以做到流量的抓取和回放。
流量回放有三种使用方式:
- 服务->to->服务,即端到端
- 服务->to->文件,即流量存储
- 文件->to->服务,即流量文件回放到服务
- 常用配置示例
- service_to_file.yml
bin:
- "/opt/crawl/project/flow_replay/gor"
input:
- "--input-raw :18080"
- "--input-raw-track-response"
- "--prettify-http"
middle:
-
output:
- "--output-file ./data/requests-%Y-%m-%d-%H.gor"
- "--output-file-size-limit 100kb"
- "--output-file-queue-limit 60" - file_to_service.yml
bin:
- "/opt/crawl/project/flow_replay/gor"
input:
- "--input-file ./data/'requests-2024-03-18-14_7.gor'"
middle:
- "--middleware /opt/crawl/project/flow_replay/middle/main.js"
output:
- "--output-http='http://localhost:18080'"
- "--output-http-track-response"
- "--prettify-http" - 释义
gorplay的配置主要分为三个部分,分别是input、output和middleware
- input:定义需要捕获请求的一些必要条件
# 定义监听端口
--input-raw :18080
# 定义是否要捕获请求响应,只有添加了这个配置,回放时才会触发response事件
--input-raw-track-response
# 定义是否要美化响应,这个配置是作者修复bug新加的配置,必须要有,
# 如果没有会造成乱码
--prettify-http
# 定义存储请求的文件位置
# 可以使用*模糊匹配,批量回放相关文件,如requests-2024-03-18-*.gor
--input-file ./data/'requests-2024-03-18-14_7.gor'
# 定义缓冲区大小,单位为b
--input-raw-buffer-size 10485760 注:不论是从端口读取请求或者从文件读取请求,则必然会触发request事件
- output:定义输出请求的一些必要参数
# 定义存储请求文件的位置、格式及命名
--output-file ./data/requests-%Y-%m-%d-%H.gor
# 追踪流量回放响应,只有存在这个配置,回放成功后才会触发replay事件
--output-http-track-response
# 定义存储请求文件的最大size
--output-file-size-limit 100kb
# 定义单个存储文件中存储请求的数量
--output-file-queue-limit 20
# 同input
--prettify-http
# 定义请求丢弃比例,分别为绝对值和百分比
# 每秒请求超过绝对值的数字,则丢弃
# 只回放百分比的请求数量提升速度
--output-http='http://localhost:18080|10'
--output-http='http://localhost:18080|10%' - 中间件
- 中间件流程示意图

- 中间件常用Api
init - 初始化
httpPath - 获取请求URL,不包含请求的域名: gor.httpPath(req.http)
httpMethod - 获取请求方法:gor.httpMethod(req.http).
setHttpPath - 更新URL: req.http = gor.setHttpPath(req.http, newPath)
httpPathParam - 获取URL上的参数: gor.httpPathParam(req.http, queryParam)
setHttpPathParam - 设置URL参数: req.http = gor.setHttpPathParam(req.http, queryParam, value)
httpStatus - 响应状态码:gor.httpStatus(rep.http)
httpHeaders - 获取所有请求头: gor.httpHeaders(req.http)
httpHeader - 获取指定请求头: gor.httpHeader(req.http, "Content-Length")
setHttpHeader - 设置请求头, returns modified payload: req.http = gor.setHttpHeader(req.http, "X-Replayed", "1")
httpBody - 获取请求体: gor.httpBody(req.http)
setHttpBody - 设置请求体,需要注意Content-Length的大小: req.http = gor.setHttpBody(req.http, Buffer.from('hello!')).
httpBodyParam - 获取post请求param: gor.httpBodyParam(req.http, param)
setHttpBodyParam - 设置post请求的param: req.http = gor.setHttpBodyParam(req.http, param, value)
httpCookie - 获取cookie: gor.httpCookie(req.http, "SESSSION_ID")
setHttpCookie - 设置cookie, returns modified payload: req.http = gor.setHttpCookie(req.http, "iam", "cuckoo")
deleteHttpCookie - 删除cookie, returns modified payload: req.http = gor.deleteHttpCookie(req.http, "iam") - 事件
事件只存在于中间件中,goreplay接收到某个端口的请求后,会把request和response压缩成gzip,通过data.http字段转发给中间件,这样会触发request事件和response事件,当回放完成后,会触发replay事件
- 中间件代码示例
#!/usr/bin/node
const gor = require("goreplay_middleware");
const NodeRSA = require('node-rsa');
const axios = require('axios')
const {user, baseUrl, publicKey} = require('./defalut')
const https = require('https');
const jsonpath = require('jsonpath');/**
* @description 对公钥进行加密
* @param publicKey
* @param {string} data 需要加密的数据
* @returns {string} 加密后的数据
*/
function encrypt(publicKey, data) {let buffer = Buffer.from(data);let key = new NodeRSA(publicKey);
key.setOptions({encryptionScheme: 'pkcs1'});return key.encrypt(buffer, 'base64', 'base64');
}/**
*
* @param str
* @param color:string, red, green, yellow, blue, and white if the color is the other value
* @return {string}
*/
function addStringColor(str, color) {switch (color) {case "red":
color = "31";break;case "green":
color = "32";break;case "yellow":
color = "33";break;case "blue":
color = "34";break;case "pink":
color = "35";break;default:
color = "37";break;}return "\x1b[" + color + "m" + str + "\x1b[0m";
}/**
* @description send login request and extract sessionId
* @param baseUrl{string} request url
* @returns {string} return sessionId
*/async function getCookie(baseUrl) {const data = {
userName: user["username"],
password: encrypt(publicKey, user["password"])};const url = baseUrl.concat('api/auth/doLogin');try {const response = await axios.post(url, data, {
httpsAgent: new https.Agent({rejectUnauthorized: false}),
headers: {'Content-Type': 'application/json; charset=utf-8'}});return response.headers['set-cookie'][0].match('(?<=JSESSIONID=)[a-f0-9-]+')[0];} catch (error) {
console.error(error);}
}(async () => {let cookie = await getCookie(baseUrl);
gor.init();
gor.on('request', function (request) {//request.http = gor.deleteHttpCookie(request.http, 'JSESSIONID')
request.http = gor.setHttpCookie(request.http, 'JSESSIONID', cookie)
gor.on("replay", request.ID, function (replay) {try {let obj = JSON.parse(gor.httpBody(replay.http).toString('utf8'))if (jsonpath.query(obj, '$..code')[0] === '0000') {
console.error(addStringColor(`√\t${gor.httpMethod(request.http)}\t${gor.httpPath(request.http)}`, 'green'))} else {
console.error(addStringColor(`x\t${gor.httpMethod(request.http)}\t${gor.httpPath(request.http)}\n ${gor.httpBody(replay.http)} `, 'red'))}} catch (e) {
console.error(addStringColor(`\t${gor.httpMethod(request.http)}\t${gor.httpPath(request.http)}\n ${e}`, 'red'))}return replay;})return request})
})() - 效果展示

相关文章:
1、goreplay流量回放
目的 在实际项目中,会有大量的回归测试工作,通常会使用自动化代码的手段来实现回归,但是对于一个庞大的系统来说,通过自动化脚本的方式来实现回归测试,又显得很费时费力。并且如果有定期将线上数据同步到测试环境的需求…...
Transformer的前世今生 day06(Self-Attention和RNN、LSTM的区别)
Self-Attention和RNN、LSTM的区别 RNN的缺点:无法做长序列,当输入很长时,最后面的输出很难参考前面的输入,即长序列会缺失上文信息,如下: 可能一段话超过50个字,输出效果就会很差了 LSTM通过忘…...
UDP send 出现大量“Resource temporarily unavailable”
背景 最近排查用户现场环境,查看日志出现大量的“send: Resource temporarily unavailable”错误,UDP设置NO_BLOCK模式,send又发生在进程上下文,并且还设置了SO_SNDBUF 为8M,在此情况下为什么还会出现发送队列满的情况…...
怎么拆解台式电脑风扇CPU风扇的拆卸步骤-怎么挑
今天我就跟大家分享一下如何选购电脑风扇的知识。 我也会解释一下机箱散热风扇一般用多少转。 如果它恰好解决了您现在面临的问题,请不要忘记关注本站并立即开始! 文章目录列表:大家一般机箱散热风扇都用多少转? 机箱散热风扇选择…...
Windows安装Odoo结合内网穿透实现公网访问本地企业管理系统
文章目录 前言1. 下载安装Odoo:2. 实现公网访问Odoo本地系统:3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件,是一个一站式全功能ERP及电商平台。 开源性质:Odoo是一个开源的ERP软件,这意味着企…...
Portainer的替代Dockge?又一个Docker Compose管理器?
Dockge:让Docker Compose管理触手可及,一图胜千言,轻松构建与管控您的容器服务栈!- 精选真开源,释放新价值。 概览 Docker,这一开放源代码的创新平台,旨在实现应用程序部署、扩展与运维的自动化…...
Midjourney AI绘图工具介绍及使用
介绍 Midjourney是一款目前被誉为最强的AI绘图工具。只要输入想到的文字,就能通过人工智能产出相对应的图片。 官网只是宣传和登录入口,提供个人主页、订阅管理等功能,Midjourney实际的绘画功能,是在另外一个叫discord的产品中实…...
clang-query 的编译安装与使用示例
1,clang query 概述 作用: 检查一个程序源码的抽象语法树,测试 AST 匹配器; 帮助检查哪些 AST 节点与指定的 AST 匹配器相匹配; 2,clang-query 安装 准备: git clone --recursive https://git…...
echarts数据下钻如何配置
官方范例:https://echarts.apache.org/examples/zh/editor.html?cbar-multi-drilldown 看了一眼范例直接晕了,你这,一堆数据直接写死,这怎么用啊! 一般来说,实现步骤是: 1)后台&a…...
git 提交空目录
git 提交空目录 1. git 无法感应空目录2. git 提交空目录References 1. git 无法感应空目录 Git FAQ https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html Currently the design of the Git index (staging area) only permits files to be liste…...
【优化方案】Java 将字符串中的星号替换为0-9中的数字,并返回所有可能的替换结果
需求 将输入的字符串中的星号替换为0-9中的数字,并返回所有可能的替换结果,允许存在多个*号。 分析: 在每个星号位置,我们需要进行 0-9 的循环遍历,因此每个星号位置都有 10 种可能性。如果字符数组中有k个星号&#x…...
C语言复习-链表
链表: 特点: 通过 next 指针 把内存上不连续 的几段数据 联系起来 set nu -- 打印行号 概念: 一种数据结构 -- 数据存放的思想 比如 -- 数组 -- 内存连续的一段空间,存放相同类型的一堆数据 缺点 -- 增删元素很 难 -- 不灵活 --> 引入链表 next指针的初步认识…...
Redis面试题-缓存雪崩、缓存穿透、缓存击穿问题
1 穿透: 两边都不存在(皇帝的新装) (黑名单) (布隆过滤器) 2 击穿:一个热点的key失效了,这时大量的并发请求直接到达数据库. (提前预热) 3 雪崩:…...
【Node.js】npx
概述 npx 可以使用户在不安装全局包的情况下,运行已安装在本地项目中的包或者远程仓库中的包。 高版本npm会自带npx命令。 它可以直接运行 node_modules/.bin 下的 exe 可执行文件。而不像之前,我们需要在 scripts 里面配置,然后 npm run …...
hive授予指定用户特定权限及beeline使用
背景:因业务需要,需要使用beeline对hive数据进行查询,但是又不希望该用户可以查询所有的数据,希望有一个新用户bb给他指定的库表权限。 解决方案: 1.赋权语句,使用hive管理员用户在终端输入hive进入命令控…...
Vmware虚拟机无法用root直连说明
Vmware虚拟机无法用root直连说明 背景目的SSH服务介绍无法连接检查配置 背景 今天在VM上新装了一套Centos-stream-9系统,网络适配器的连接方式采用的是桥接,安装好虚拟机后,在本地用ssh工具进行远程连接,ip、用户、密码均是成功的…...
Visio中存在问题的解决方法
公式缩放 mathtype公式在visio缩放之后,出现了变形。 解决方法:每次输入公式都通过 插入->对象->mathType Equation 新建一个公式。可以避免 注:网上有的说在word中使用mathtype编写公式,之后复制到visio中。 插入波形 选择…...
taro之Swiper的使用
图样: 往往我们需要轮播图去显示我们想要的图片之类的 这是工作的代码 <View classNametop-title><SwiperclassNamebanner-swiperinterval{3000}circularautoplay>{homeBannerList.map((item) > {return (<SwiperItem key{item.id}><View…...
正大国际:金融行业发展趋势
2024金融科技趋势研究报告 大模型生态揭秘!金融行业迎来变革,中控成生态核心,大模型在金融行业的应用 随着大模型的不断发展,越来越多的金融机构开始尝试在一些业务场景中引入大模型和生成式A能力,预计2024年,领先的金…...
vue中实现超出一行 展开和收起的功能
html中: <divclass="txttype"ref="txttype"style="margin-bottom: 6px":class="hidetext == true ? hidetext : "><div style="width: 96%"><el-tagtype="info"style="margin-right: 10px&…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
