不灭的焱

革命尚未成功,同志仍须努力 下载Go 下载Java

作者:AlbertWen  添加时间:2026-02-05 13:08:39  修改时间:2026-02-05 20:07:38  分类:17.性能测试/JMeter  编辑

章节1:GoReplay 安装、基础用法

GoReplay 是 Go 编写的 HTTP 流量录制 / 回放工具,可用于线上流量复制、压测与回归测试。以下是快速上手与常用场景实操。

一、安装与准备

  1. 下载安装(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/
  1. 权限说明:抓包需 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

四、常见问题与安全

  1. 抓包时避免敏感数据(如密码),过滤 / 脱敏处理。
  2. 回放时注意幂等性,避免重复提交订单等操作。
  3. 生产环境建议先采样,观察无异常再逐步放大流量。
  4. 遇到端口占用:更换--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 "清理完成"

脚本使用与管理规范(开发 / 运维视角)

  1. 权限控制:所有脚本需通过 sudo 执行(抓包需 root),建议仅授权运维和测试人员使用,避免生产误操作。
  2. 环境隔离:生产环境仅执行「录制」和「转发」脚本,且转发时必须设置采样率;「回放」仅在测试环境执行。
  3. 幂等性风险:回放前需确认测试环境无业务数据(如订单、支付记录),避免重复提交导致数据污染。
  4. 监控告警:可在脚本中添加磁盘占用监控(如 df -h | grep /data | awk '{if($5>80) print "磁盘占用过高"}'),触发邮件或企业微信告警。
  5. 版本管理:将脚本纳入 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. 安全最佳实践

  1. 敏感数据深度脱敏:在 filter_sensitive.js 中增加对 CookieAuthorization 头的过滤。
  2. 网络隔离:确保测试环境无法直接访问生产数据库,避免流量回放时的误操作。
  3. 白名单机制:在转发脚本中使用 --http-allow-ip 限制仅允许特定 IP 的流量被转发。
  4. 监控指标:使用 ps aux | grep gor 结合 Zabbix/Prometheus 监控进程状态,或监听 --stats 端口(gor --stats :8181)获取实时流量指标。

3. CI/CD 集成建议

可以将 gor_compare.sh 集成到 Jenkins/GitLab CI 的流水线中:

  1. 构建阶段:部署新版本到测试环境。
  2. 测试阶段:运行 gor_compare.sh
  3. 判断阶段:如果报告中 ERROR_COUNT > 0,则标记流水线失败,阻止发布。

 

章节4:GoReplay能抓https流量吗?   

GoReplay 能抓 HTTPS 流量,但无法直接解密,需通过 “让 Gor 读取明文流量” 的方式实现,生产环境优先推荐网关 / 负载均衡卸载 TLS的方案。

核心原理与可行方案

  • 原理:GoReplay 基于 libpcap 抓包,对 443 端口的 HTTPS 流量只能拿到加密的 TLS 记录,无法解析 HTTP 内容;必须让它接触解密后的明文才能正常录制 / 转发。
  • 方案对比(按生产推荐度排序)
    1. 网关 / 负载均衡卸载 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
    2. 应用内直接输出明文(次选):通过--input-http让应用将请求负载直接发给 Gor(如在代码中加一行转发逻辑),无网络抓包开销,但需修改应用。示例:Gor 启动sudo gor --input-http :8081 --output-file app_payload.gor,应用侧将请求 POST 到http://127.0.0.1:8081
    3. Sidecar / 本地代理卸载(测试环境用):在应用同机部署 Nginx 作为本地 HTTPS 代理,Gor 监听代理后的明文端口,适合无集中网关的场景。示例:Nginx 监听 443 并转发到 8080,Gor 监听 8080。
    4. eBPF 辅助获取明文(进阶):用 eCapture 等工具在进程侧拿到应用已解密的 HTTP 数据,再导入 Gor,无需改应用也不碰 TLS 密钥,但依赖 Linux eBPF 环境

生产落地关键配置(Nginx+Gor 示例)

  1. 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;
        }
    }
  2. 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 &
  3. 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 环境