霸王餐API接口流量录制:GoReplay与Java Diffy回归测试方案
背景与目标
“吃喝不愁”App计划对核心霸王餐接口 /api/v1/free-meal/claim 进行重构(如数据库分库、逻辑优化)。为确保新版本行为与旧版一致,采用 GoReplay 录制线上真实流量,并通过 Diffy 对比新旧服务响应差异,实现自动化回归验证。
架构拓扑
生产流量
↓
Nginx (监听80)
↓
GoReplay 中间代理 (监听7000)
↓
旧服务 (v1, 8080) ←┐
├─ Diffy (9999)
新服务 (v2, 8081) ←┘
GoReplay 流量录制与重放
在网关服务器部署 GoReplay:
# 录制生产流量(仅GET/POST到特定路径)
sudo goreplay --input-raw :80 \
--input-raw-track-response \
--output-file max-size=10000 claim-traffic.gor
# 过滤非目标请求(可选)
sudo goreplay --input-raw :80 \
--input-raw-filter "url ~ /api/v1/free-meal" \
--output-file claim-traffic.gor
重放至 Diffy:
goreplay --input-file claim-traffic.gor \
--output-http "http://localhost:9999"

Diffy 服务部署(Docker)
docker run -d \
--name diffy \
-p 9999:9999 \
-p 9990:9990 \
-p 9991:9991 \
diffy/diffy \
-candidate="host.docker.internal:8081" \
-master.primary="host.docker.internal:8080" \
-master.secondary="host.docker.internal:8080" \
-service.protocol="http" \
-serviceName="FreeMealClaimAPI" \
-proxy.port=:9999 \
-admin.port=:9990 \
-http.port=:9991 \
-rootUrl="localhost:9991"
说明:
candidate:新版本服务(v2);master.primary/secondary:旧版本服务(v1),用于消除非确定性噪声;- 所有服务需在同一主机或配置 DNS 可达。
Java 服务代码示例(含非确定字段)
旧服务(juwatech.cn.v1.FreeMealController):
package juwatech.cn.v1;
import org.springframework.web.bind.annotation.*;
import java.time.Instant;
import java.util.UUID;
@RestController
public class FreeMealController {
@PostMapping("/api/v1/free-meal/claim")
public ClaimResponse claim(@RequestBody ClaimRequest req) {
// 模拟业务逻辑
return new ClaimResponse(
true,
"SUCCESS",
UUID.randomUUID().toString(), // 非确定字段
Instant.now().toEpochMilli(), // 非确定字段
req.getUserId() + "-meal-2025"
);
}
}
新服务(juwatech.cn.v2.FreeMealController)逻辑相同,但 UUID 生成方式变更(如改用雪花ID)。
Diffy 忽略非确定性字段
Diffy 默认会将 UUID 和时间戳差异标记为“潜在 bug”。需通过 忽略规则 排除:
访问 http://localhost:9991,在 Web UI 中配置:
Candidate-Only Differences to Ignore:
$.traceId
$.timestamp
Primary vs Secondary Differences to Ignore:
$.traceId
$.timestamp
或启动时通过参数指定(需自定义 Diffy 镜像):
-ignore-fields='["traceId","timestamp"]'
自动化回归脚本
编写 run_regression.sh:
#!/bin/bash
# 1. 启动新旧服务(略)
# 2. 启动 Diffy(见上)
# 3. 重放流量
goreplay --input-file claim-traffic.gor --output-http "http://localhost:9999"
# 4. 等待完成
sleep 30
# 5. 检查是否有差异
DIFF_COUNT=$(curl -s http://localhost:9991/count/potential_bugs | jq '.count')
if [ "$DIFF_COUNT" -gt 0 ]; then
echo "Regression failed: $DIFF_COUNT differences found"
curl http://localhost:9991/issues > regression_report.json
exit 1
else
echo "Regression passed"
fi
关键注意事项
- 幂等性:被测接口必须幂等,否则重放会污染数据。可在请求头加
X-Replay: true,服务端识别后跳过写库; - 敏感数据脱敏:GoReplay 支持正则替换,避免录制用户手机号等;
- 性能隔离:Diffy 和被测服务应部署在独立机器,防止资源争抢;
- 状态清理:每次回归前清空测试数据库。
扩展:集成CI/CD
在 Jenkins Pipeline 中调用:
stage('Regression Test') {
steps {
sh './run_regression.sh'
archiveArtifacts 'regression_report.json'
}
}
若发现差异,构建失败并通知开发者。
本文著作权归吃喝不愁app开发者团队,转载请注明出处!


被折叠的 条评论
为什么被折叠?



