章节1:GoReplay 安装、基础用法
GoReplay 是 Go 编写的 HTTP 流量录制 / 回放工具,可用于线上流量复制、压测与回归测试。以下是快速上手与常用场景实操。
一、安装与准备
- 下载安装(Linux)
# 下载最新版(替换版本号) wget https://github.com/probelabs/goreplay/releases/download/1.3.3/gor_1.3.3_x64.tar.gz tar -xzvf gor_1.3.3_x64.tar.gz sudo chmod +x gor sudo mv gor /usr/local/bin/
- 权限说明:抓包需 root,建议测试环境使用,避免生产风险。
二、核心场景命令
- 实时流量转发(生产→测试)
sudo gor --input-raw :80 --output-http "http://staging.example.com"
- 流量录制到文件
sudo gor --input-raw :8080 --output-file requests.gor
- 从文件回放(按原时序)
gor --input-file requests.gor --output-http "http://localhost:8001"
- 压测(加速 2 倍)
gor --input-file "requests.gor|200%" --output-http "http://test.env"
- 流量过滤(仅 POST,含 test)
sudo gor --input-raw :8080 --output-http staging.com \ --http-allow-method POST \ --http-allow-url test
- 流量复制与分流(两份输出)
sudo gor --input-raw :80 --output-http "http://staging1" --output-http "http://staging2"
- 流量采样(复制 10% 到 TCP 转发)
sudo gor --input-raw :80 --output-tcp "replay.local:28020|10%"
三、高级用法
- 中间件扩展(JavaScript 示例)
// echo.js module.exports = function(req, res) { res.setHeader("X-Replayed-By", "Gor"); return res.send(req.body); }; // 运行 gor --input-raw :80 --middleware "./echo.js" --output-http "http://staging" - 响应对比(测试与生产结果校验)
gor --input-raw :80 --output-http "http://staging" --output-http "http://prod" \ --http-compare-output
- 性能调优:调整并发与缓冲
gor --input-raw :80 --output-http "http://staging" \ --output-http-workers=10 \ --http-buffer-size=10000
四、常见问题与安全
- 抓包时避免敏感数据(如密码),过滤 / 脱敏处理。
- 回放时注意幂等性,避免重复提交订单等操作。
- 生产环境建议先采样,观察无异常再逐步放大流量。
- 遇到端口占用:更换
--input-raw端口或停止占用进程。
五、命令速查
| 命令 | 用途 |
|---|---|
gor -h |
查看所有参数 |
--input-raw :port |
监听端口抓包 |
--output-file file.gor |
流量存文件 |
--output-http url |
转发到目标服务 |
--http-allow-method GET |
只允许 GET 方法 |
--http-set-header key:val |
自定义请求头 |
章节2:GoReplay 一键执行脚本(生产 / 测试环境通用)
脚本已按开发 / 运维管理视角结构化设计,包含流量录制、实时转发、回放压测、敏感数据过滤等核心场景,适配 Linux 环境,可直接复制到服务器执行,也可集成到 CI/CD 或运维自动化平台。
前置准备(必选)
#!/bin/bash
# 脚本初始化:安装 GoReplay、创建工作目录、定义全局变量
# 适用场景:首次部署或服务器初始化
# 执行权限:sudo chmod +x gor_init.sh && sudo ./gor_init.sh
set -e # 出错立即退出
WORK_DIR="/data/goreplay" # 流量文件、日志存储目录
GOR_VERSION="1.3.3" # 建议固定版本,避免自动更新导致兼容性问题
TARGET_ARCH="x64" # 架构:x64/arm64
# 创建工作目录
mkdir -p ${WORK_DIR}/{record,playback,log,script}
chmod 755 ${WORK_DIR} -R
# 安装 GoReplay
if ! command -v gor &> /dev/null; then
echo "正在安装 GoReplay v${GOR_VERSION}..."
wget -q https://github.com/buger/goreplay/releases/download/v${GOR_VERSION}/gor_${GOR_VERSION}_${TARGET_ARCH}.tar.gz -O /tmp/gor.tar.gz
tar -xzf /tmp/gor.tar.gz -C /tmp
sudo mv /tmp/gor /usr/local/bin/
gor -v && echo "GoReplay 安装成功" || (echo "安装失败" && exit 1)
else
echo "GoReplay 已安装,版本:$(gor -v)"
fi
# 生成敏感数据过滤规则(默认过滤密码、token)
cat > ${WORK_DIR}/script/filter_sensitive.js << EOF
// 敏感数据脱敏中间件:过滤请求体中的 password、token 字段
module.exports = function(req, res) {
if (req.body) {
req.body = req.body.replace(/(password|token)=[^&]*/g, '$1=***');
}
return req;
};
EOF
echo "初始化完成,工作目录:${WORK_DIR}"
场景 1:生产流量录制(安全采样版)
用途:录制生产环境指定端口的流量,仅采样 10% 并脱敏,避免存储敏感数据,适用于后续回归测试 / 压测。
#!/bin/bash
# 生产流量录制脚本(安全版)
# 执行权限:sudo chmod +x gor_record_prod.sh && sudo ./gor_record_prod.sh
# 停止方式:ps -ef | grep gor | grep record | awk '{print $2}' | xargs sudo kill
set -e
WORK_DIR="/data/goreplay"
RECORD_PORT="80" # 生产服务监听端口
SAMPLE_RATE="10%" # 流量采样率,生产建议 5%-20%
OUTPUT_FILE="${WORK_DIR}/record/prod_traffic_$(date +%Y%m%d_%H%M%S).gor"
FILTER_SCRIPT="${WORK_DIR}/script/filter_sensitive.js"
LOG_FILE="${WORK_DIR}/log/record_$(date +%Y%m%d).log"
# 启动录制:过滤敏感数据、仅保留 GET/POST 请求、记录日志
echo "开始录制生产流量(端口:${RECORD_PORT},采样率:${SAMPLE_RATE}),日志:${LOG_FILE}"
sudo nohup gor \
--input-raw :${RECORD_PORT} \
--output-file "${OUTPUT_FILE}|${SAMPLE_RATE}" \
--middleware "${FILTER_SCRIPT}" \
--http-allow-method GET \
--http-allow-method POST \
--http-deny-url "/admin" \ # 排除管理后台流量
--log-file "${LOG_FILE}" \
--verbose 1 > /dev/null 2>&1 &
echo "录制进程已启动,流量文件:${OUTPUT_FILE}"
场景 2:实时流量转发(生产→测试)
用途:将生产流量实时复制到测试环境,用于验证测试环境兼容性,支持流量放大 / 缩小。
#!/bin/bash
# 实时流量转发脚本
# 执行权限:sudo chmod +x gor_forward.sh && sudo ./gor_forward.sh
# 停止方式:ps -ef | grep gor | grep forward | awk '{print $2}' | xargs sudo kill
set -e
WORK_DIR="/data/goreplay"
PROD_PORT="80" # 生产服务端口
STAGING_URL="http://10.0.0.10:8080" # 测试环境地址(替换为实际地址)
TRAFFIC_MULTIPLIER="100%" # 流量放大倍数,100% 为原流量,200% 为2倍
LOG_FILE="${WORK_DIR}/log/forward_$(date +%Y%m%d).log"
# 启动转发:添加标识头、限制并发、记录日志
echo "开始转发生产流量到测试环境(生产端口:${PROD_PORT},测试地址:${STAGING_URL}),日志:${LOG_FILE}"
sudo nohup gor \
--input-raw :${PROD_PORT} \
--output-http "${STAGING_URL}|${TRAFFIC_MULTIPLIER}" \
--output-http-workers 20 \ # 并发数,根据测试环境性能调整
--http-set-header "X-Gor-Forward: true" \ # 标记转发流量
--http-timeout 30s \ # 超时时间
--log-file "${LOG_FILE}" \
--verbose 1 > /dev/null 2>&1 &
echo "转发进程已启动"
场景 3:流量回放(回归测试 / 压测)
用途:使用录制的流量文件,在测试环境按原时序或加速回放,支持压测场景的流量放大。
#!/bin/bash
# 流量回放脚本(支持压测)
# 执行权限:chmod +x gor_playback.sh && ./gor_playback.sh
# 入参:1-流量文件路径 2-目标测试地址 3-回放倍数(默认100%)
# 示例:./gor_playback.sh /data/goreplay/record/prod_traffic_20260205.gor http://10.0.0.10:8080 200%
set -e
WORK_DIR="/data/goreplay"
TRAFFIC_FILE=$1
TARGET_URL=$2
PLAYBACK_MULTIPLIER=${3:-"100%"} # 默认原速回放
LOG_FILE="${WORK_DIR}/log/playback_$(date +%Y%m%d_%H%M%S).log"
# 校验入参
if [ -z "${TRAFFIC_FILE}" ] || [ -z "${TARGET_URL}" ]; then
echo "用法:$0 <流量文件路径> <目标测试地址> [回放倍数]"
exit 1
fi
if [ ! -f "${TRAFFIC_FILE}" ]; then
echo "错误:流量文件 ${TRAFFIC_FILE} 不存在"
exit 1
fi
# 启动回放:调整并发、忽略幂等性风险(仅测试环境)、记录响应
echo "开始回放流量(文件:${TRAFFIC_FILE},目标地址:${TARGET_URL},回放倍数:${PLAYBACK_MULTIPLIER}),日志:${LOG_FILE}"
nohup gor \
--input-file "${TRAFFIC_FILE}|${PLAYBACK_MULTIPLIER}" \
--output-http "${TARGET_URL}" \
--output-http-workers 50 \ # 压测时可提高并发
--http-ignore-headers "Authorization" \ # 测试环境可忽略认证(按需调整)
--http-print-response \ # 打印响应内容到日志
--log-file "${LOG_FILE}" \
--verbose 2 > /dev/null 2>&1 &
echo "回放进程已启动,日志:${LOG_FILE}"
场景 4:流量清理与日志轮转(运维定时任务)
用途:定期清理过期流量文件和日志,避免磁盘占用过高,可添加到 crontab 定时执行。
#!/bin/bash
# 流量文件清理脚本
# 执行权限:sudo chmod +x gor_cleanup.sh && sudo ./gor_cleanup.sh
# 定时任务:echo "0 0 * * * /data/goreplay/gor_cleanup.sh" | sudo tee -a /etc/crontab
set -e
WORK_DIR="/data/goreplay"
RETENTION_DAYS=7 # 保留7天内的文件
# 清理过期流量文件
echo "清理 ${RETENTION_DAYS} 天前的流量文件..."
find ${WORK_DIR}/record -name "*.gor" -mtime +${RETENTION_DAYS} -delete
# 清理过期日志
echo "清理 ${RETENTION_DAYS} 天前的日志文件..."
find ${WORK_DIR}/log -name "*.log" -mtime +${RETENTION_DAYS} -delete
# 清理空文件
find ${WORK_DIR} -type f -size 0 -delete
echo "清理完成"
脚本使用与管理规范(开发 / 运维视角)
- 权限控制:所有脚本需通过
sudo执行(抓包需 root),建议仅授权运维和测试人员使用,避免生产误操作。 - 环境隔离:生产环境仅执行「录制」和「转发」脚本,且转发时必须设置采样率;「回放」仅在测试环境执行。
- 幂等性风险:回放前需确认测试环境无业务数据(如订单、支付记录),避免重复提交导致数据污染。
- 监控告警:可在脚本中添加磁盘占用监控(如
df -h | grep /data | awk '{if($5>80) print "磁盘占用过高"}'),触发邮件或企业微信告警。 - 版本管理:将脚本纳入 Git 版本控制,修改时记录变更日志,避免多人协作时的版本混乱。
章节3:GoReplay 服务化与响应校验增强包
为了适配开发 / 运维经理的管理视角,以下补充 Systemd 服务配置(实现进程守护、开机自启、日志轮转)和 响应对比脚本(自动校验生产与测试环境的接口一致性)。这些配置可直接用于生产环境的标准化部署。
第一部分:Systemd 服务配置(进程守护)
将 GoReplay 注册为 Systemd 服务,可实现 systemctl start/stop/restart 管理,配合内置的日志轮转,解决 nohup 日志过大和进程意外退出的问题。
1. 目录结构
# 建议将服务文件放在标准目录 sudo mkdir -p /etc/systemd/system/goreplay.service.d
2. 实时转发服务(gor-forward.service)
用途:长期运行的生产→测试流量复制任务。
# /etc/systemd/system/gor-forward.service [Unit] Description=GoReplay Traffic Forwarding Service After=network.target Documentation=man:gor(1) [Service] Type=simple User=root # 抓包必须root Group=root # 指向你之前的转发脚本,确保脚本中有绝对路径 ExecStart=/data/goreplay/gor_forward.sh # 意外退出后自动重启 Restart=always RestartSec=5s # 日志配置,默认输出到journald StandardOutput=journal+console StandardError=journal+console # 资源限制 LimitNOFILE=65535 LimitNPROC=4096 [Install] WantedBy=multi-user.target
3. 流量录制服务(gor-record.service)
用途:长期或定时录制生产流量。
# /etc/systemd/system/gor-record.service [Unit] Description=GoReplay Traffic Recording Service After=network.target [Service] Type=simple User=root Group=root ExecStart=/data/goreplay/gor_record_prod.sh Restart=on-failure # 录制脚本通常是无限循环,失败时重启 RestartSec=10s StandardOutput=journal+console StandardError=journal+console LimitNOFILE=65535 [Install] WantedBy=multi-user.target
4. 操作与管理命令
# 重新加载 Systemd 配置 sudo systemctl daemon-reload # 启动并设置开机自启(以转发为例) sudo systemctl start gor-forward sudo systemctl enable gor-forward # 查看状态与日志 sudo systemctl status gor-forward sudo journalctl -u gor-forward -f # 实时查看日志 sudo journalctl -u gor-forward --since "1 hour ago" # 查看最近1小时日志 # 停止服务 sudo systemctl stop gor-forward
第二部分:响应对比脚本(自动校验)
该脚本基于 GoReplay 的 --output-http-compare 功能,自动对比生产环境和测试环境的响应差异(状态码、响应体、响应头),生成结构化报告,适用于回归测试和版本发布前的验证。
1. 智能对比脚本(gor_compare.sh)
#!/bin/bash
# 流量响应对比脚本
# 用途:对比录制的流量在生产和测试环境的响应差异
# 执行:sudo chmod +x gor_compare.sh && ./gor_compare.sh <流量文件>
# 输出:差异报告存放在 /data/goreplay/report
set -e
WORK_DIR="/data/goreplay"
TRAFFIC_FILE=$1
REPORT_DIR="${WORK_DIR}/report"
REPORT_FILE="${REPORT_DIR}/compare_report_$(date +%Y%m%d_%H%M%S).txt"
PROD_URL="http://127.0.0.1:80" # 生产地址(建议内网VIP)
TEST_URL="http://10.0.0.10:8080" # 测试地址
# 校验入参
if [ -z "${TRAFFIC_FILE}" ] || [ ! -f "${TRAFFIC_FILE}" ]; then
echo "错误:请提供有效的流量文件路径"
echo "用法:$0 /path/to/traffic.gor"
exit 1
fi
# 创建报告目录
mkdir -p ${REPORT_DIR}
echo "==================================================" | tee -a ${REPORT_FILE}
echo "GoReplay 响应对比报告 - $(date)" | tee -a ${REPORT_FILE}
echo "流量文件:${TRAFFIC_FILE}" | tee -a ${REPORT_FILE}
echo "生产环境:${PROD_URL}" | tee -a ${REPORT_FILE}
echo "测试环境:${TEST_URL}" | tee -a ${REPORT_FILE}
echo "==================================================" | tee -a ${REPORT_FILE}
echo "" | tee -a ${REPORT_FILE}
# 核心命令:使用 GoReplay 内置对比功能
# --output-http-compare: 开启对比模式
# --http-compare-output: 输出差异到stdout
echo "正在执行对比...(耗时取决于流量文件大小)"
sudo gor \
--input-file ${TRAFFIC_FILE} \
--output-http ${PROD_URL} \
--output-http ${TEST_URL} \
--http-compare-output \
--http-verbose-compare \
--output-http-workers 10 # 对比时建议降低并发,避免资源竞争
2>&1 | tee -a ${REPORT_FILE}
# 统计报告
ERROR_COUNT=$(grep -c "Response Mismatch" ${REPORT_FILE})
echo "" | tee -a ${REPORT_FILE}
echo "==================================================" | tee -a ${REPORT_FILE}
echo "对比完成!差异总数:${ERROR_COUNT}" | tee -a ${REPORT_FILE}
echo "完整报告已保存至:${REPORT_FILE}" | tee -a ${REPORT_FILE}
echo "==================================================" | tee -a ${REPORT_FILE}
# 发送告警(可选,集成企业微信/钉钉)
if [ ${ERROR_COUNT} -gt 0 ]; then
echo "发现 ${ERROR_COUNT} 处差异,请及时处理!"
# 这里可以添加 curl 调用企业微信机器人的命令
fi
2. 对比报告解读示例
脚本会生成类似以下的报告,帮助快速定位问题:
# 匹配成功的请求
[MATCH] GET /api/user/123 | Status: 200 | Body Size: 1024 | Headers Match
# 响应不匹配的请求(重点关注)
[Response Mismatch] GET /api/payment
URL: /api/payment
Production Status: 200
Test Status: 500
Production Body: {"code":0,"msg":"success"}
Test Body: {"code":-1,"msg":"database error"}
Header Diff: X-Request-ID: prod-123 vs test-456
第三部分:企业级运维规范(补充)
1. 日志轮转配置
虽然 Systemd 的 journald 有自动轮转,但建议为单独的日志文件配置 logrotate:
# /etc/logrotate.d/goreplay
/data/goreplay/log/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0644 root root
}
2. 安全最佳实践
- 敏感数据深度脱敏:在
filter_sensitive.js中增加对Cookie和Authorization头的过滤。 - 网络隔离:确保测试环境无法直接访问生产数据库,避免流量回放时的误操作。
- 白名单机制:在转发脚本中使用
--http-allow-ip限制仅允许特定 IP 的流量被转发。 - 监控指标:使用
ps aux | grep gor结合 Zabbix/Prometheus 监控进程状态,或监听--stats端口(gor --stats :8181)获取实时流量指标。
3. CI/CD 集成建议
可以将 gor_compare.sh 集成到 Jenkins/GitLab CI 的流水线中:
- 构建阶段:部署新版本到测试环境。
- 测试阶段:运行
gor_compare.sh。 - 判断阶段:如果报告中
ERROR_COUNT > 0,则标记流水线失败,阻止发布。
章节4:GoReplay能抓https流量吗?
GoReplay 能抓 HTTPS 流量,但无法直接解密,需通过 “让 Gor 读取明文流量” 的方式实现,生产环境优先推荐网关 / 负载均衡卸载 TLS的方案。
核心原理与可行方案
- 原理:GoReplay 基于 libpcap 抓包,对 443 端口的 HTTPS 流量只能拿到加密的 TLS 记录,无法解析 HTTP 内容;必须让它接触解密后的明文才能正常录制 / 转发。
- 方案对比(按生产推荐度排序):
- 网关 / 负载均衡卸载 TLS(首选):将 HTTPS 终止在 Nginx/HAProxy/ 云 LB,Gor 监听后端明文 HTTP 端口(如 8080),配置简单、无侵入、安全可控。示例:Nginx 配置
proxy_pass http://127.0.0.1:8080;,Gor 执行sudo gor --input-raw :8080 --output-file prod_https.gor。 - 应用内直接输出明文(次选):通过
--input-http让应用将请求负载直接发给 Gor(如在代码中加一行转发逻辑),无网络抓包开销,但需修改应用。示例:Gor 启动sudo gor --input-http :8081 --output-file app_payload.gor,应用侧将请求 POST 到http://127.0.0.1:8081。 - Sidecar / 本地代理卸载(测试环境用):在应用同机部署 Nginx 作为本地 HTTPS 代理,Gor 监听代理后的明文端口,适合无集中网关的场景。示例:Nginx 监听 443 并转发到 8080,Gor 监听 8080。
- eBPF 辅助获取明文(进阶):用 eCapture 等工具在进程侧拿到应用已解密的 HTTP 数据,再导入 Gor,无需改应用也不碰 TLS 密钥,但依赖 Linux eBPF 环境。
- 网关 / 负载均衡卸载 TLS(首选):将 HTTPS 终止在 Nginx/HAProxy/ 云 LB,Gor 监听后端明文 HTTP 端口(如 8080),配置简单、无侵入、安全可控。示例:Nginx 配置
生产落地关键配置(Nginx+Gor 示例)
- Nginx TLS 卸载配置(/etc/nginx/conf.d/app.conf):
server { listen 443 ssl; server_name your-domain.com; # 证书配置 ssl_certificate /path/fullchain.pem; ssl_certificate_key /path/privkey.pem; # 转发到应用明文端口 location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } - Gor 录制明文流量:
#!/bin/bash WORK_DIR="/data/goreplay" LOG_FILE="${WORK_DIR}/log/record_https_$(date +%Y%m%d).log" # 监听Nginx转发后的明文端口8080 sudo nohup gor \ --input-raw :8080 \ --output-file "${WORK_DIR}/record/prod_https_$(date +%Y%m%d_%H%M%S).gor|10%" \ --middleware "${WORK_DIR}/script/filter_sensitive.js" \ --http-allow-method GET --http-allow-method POST \ --log-file "${LOG_FILE}" \ --verbose 1 > /dev/null 2>&1 & - Systemd 管理 Gor 进程(复用之前的 gor-record.service,只需修改 ExecStart 指向上述脚本)。
避坑指南
- ❌ 不要直接抓 443 端口:只会得到加密数据,Gor 无法解析 HTTP 内容。
- ❌ 禁止 MITM 中间人解密:生产环境会引入证书信任风险,且易被证书固定(Certificate Pinning)拦截。
- ⚠️ 大请求处理:HTTPS 大请求(如 > 200KB)需设置
--input-raw-override-snaplen 65536,避免包截断。 - ⚠️ 敏感数据防护:明文录制时务必启用之前的
filter_sensitive.js,过滤 password、token 等字段。
快速决策表
| 场景 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 生产环境(有网关) | 网关卸载 TLS+Gor 抓明文 | 无侵入、安全、易维护 | 需调整网关配置 |
| 生产环境(无网关) | 应用内--input-http输出 |
无需网络抓包、性能好 | 需修改应用代码 |
| 测试 / 预发环境 | 本地 Nginx 代理 + Gor 抓明文 | 配置简单、不影响生产 | 仅适合测试环境 |
| 需深度分析加密流量 | eBPF 辅助获取明文 | 无需改应用、不碰 TLS 密钥 | 依赖 Linux eBPF 环境 |