腾讯-百度追踪回传系统 (tencent-baidu-tracking) 测试文档
一、项目概述
本系统是腾讯广告平台与百度ADX之间的追踪和转化回传中转服务器,主要功能:
- 接收腾讯曝光/点击监测请求
- 向百度ADX发起竞价请求并上报追踪事件
- 定时从百度拉取转化数据并回传给腾讯
- 失败回调自动重试
技术栈:Java 17 / Spring Boot 3.2.5 / MyBatis 3.0.3 / Redis (Lettuce) / MySQL(TiDB)
二、测试环境要求
| 组件 |
版本/配置 |
| JDK |
17+ |
| Redis |
6.0+ (需支持 Stream) |
| MySQL/TiDB |
5.7+ / TiDB 6.0+ |
| Maven |
3.8+ |
| Profile |
application-test.yml |
环境准备:
- Redis 地址: 配置在
application-test.yml 的 adx.redis-addr
- MySQL/TiDB: 配置在
adx.tidb-url,需预先创建数据库 adx_tencent
- 系统自动建表(
TiDBColdStore.migrate())
三、API 接口测试
3.1 健康检查
| 项目 |
说明 |
| 端点 |
GET /health |
| 预期响应 |
200 OK,Body: {"ok": true} |
测试用例:
| 编号 |
场景 |
请求 |
预期结果 |
| HC-01 |
正常健康检查 |
GET /health |
200, {"ok":true} |
| HC-02 |
服务启动后立即检查 |
GET /health |
200, {"ok":true} |
3.2 曝光监测接口
| 项目 |
说明 |
| 端点 |
GET /tencent/impression |
| 必需参数 |
至少一个: click_id, trace_id, callback, request_id, oaid, imei, idfa, caid |
| 成功响应 |
204 No Content |
测试用例:
| 编号 |
场景 |
请求参数 |
预期结果 |
| IMP-01 |
正常曝光(click_id) |
?click_id=test123&platform=android |
204 No Content |
| IMP-02 |
正常曝光(oaid) |
?oaid=abc123&platform=android |
204 No Content |
| IMP-03 |
正常曝光(imei) |
?imei=def456&platform=android |
204 No Content |
| IMP-04 |
正常曝光(idfa+ios) |
?idfa=guid123&platform=ios |
204 No Content |
| IMP-05 |
缺少 trace id |
?platform=android |
400, {"error":"missing media trace id..."} |
| IMP-06 |
空 trace id |
?click_id=&platform=android |
400, {"error":"missing media trace id..."} |
| IMP-07 |
无 platform 且有默认配置 |
?click_id=test123 |
204(使用默认 baidu_app_id/tag_id) |
| IMP-08 |
无 platform 且无默认配置 |
?click_id=test123(未配置默认) |
400, {"error":"missing baidu_tag_id or platform"} |
| IMP-09 |
指定 baidu_tag_id |
?click_id=x&baidu_tag_id=tag001 |
204 |
| IMP-10 |
无效的 baidu_tag_id |
?click_id=x&baidu_tag_id=invalid |
400, {"error":"unknown baidu tag id: invalid"} |
| IMP-11 |
百度 ADX 返回空响应 |
模拟百度返回空 |
502, {"error":"empty baidu ADX response"} |
| IMP-12 |
百度 ADX 网络超时 |
模拟网络超时 |
502, {"error":"..."} |
验证点:
- Redis 中应存在 bid 缓存键:
adx:tencent:bid:{qk} 和 adx:tencent:media:tencent:{traceId}
- Redis Stream
adx:tencent:events 中应有 type=bid 的事件
- 若有 showUrls,应能看到 impression tracking 的 Stream 事件
3.3 点击监测接口
| 项目 |
说明 |
| 端点 |
GET /tencent/click |
| 必需参数 |
至少一个: click_id, trace_id, callback, request_id, oaid, imei, idfa, caid |
| 成功响应 |
302 Redirect(重定向到落地页/应用商店) |
测试用例:
| 编号 |
场景 |
请求参数 |
预期结果 |
| CLK-01 |
已有 bid 记录(重定向到 landingPage) |
?click_id=test123&platform=android |
302, Location=landingPage |
| CLK-02 |
已有 bid 记录(重定向到 appStoreLink) |
?click_id=test123&platform=ios |
302, Location=appStoreLink |
| CLK-03 |
无 bid 记录(临时竞价) |
?click_id=newId&platform=android |
302 或 JSON |
| CLK-04 |
缺少 trace id |
?platform=android |
400, {"error":"missing media trace id..."} |
| CLK-05 |
无重定向目标 |
?click_id=noDest&platform=android |
200 JSON: {"qk":"...","traceId":"...","tracking":[...]} |
| CLK-06 |
百度点击上报失败(不影响重定向) |
模拟点击 URL 返回 500 |
仍然 302 重定向 |
| CLK-07 |
百度 ADX 竞价失败(无已有 bid) |
模拟 ADX 返回错误 |
502, {"error":"..."} |
验证点:
- 点击上报后 Redis Stream 应有 type=tracking, kind=click 的事件
- 302 重定向的 Location 头应为有效 URL
3.4 管理接口
3.4.1 查询百度转化
| 项目 |
说明 |
| 端点 |
POST /admin/conversions/query |
| Content-Type |
application/json |
| 请求体 |
{"date":"20260702","pageSize":1,"acts":[1,2]} |
测试用例:
| 编号 |
场景 |
请求体 |
预期结果 |
| AQ-01 |
正常查询 |
{"date":"20260702","pageSize":1} |
200, ConversionResponse |
| AQ-02 |
缺少 date |
{"pageSize":1} |
400, {"error":"date is required"} |
| AQ-03 |
pageSize 无效 |
{"date":"20260702","pageSize":0} |
400, {"error":"pageSize must be > 0"} |
| AQ-04 |
百度 API 返回错误码 |
模拟百度返回 code!=200 |
502, {"error":"Baidu conversion API failed: ..."} |
3.4.2 手动触发转化同步
| 项目 |
说明 |
| 端点 |
POST /admin/conversions/sync |
| Content-Type |
application/json |
测试用例:
| 编号 |
场景 |
请求体 |
预期结果 |
| AS-01 |
正常同步 |
{"date":"20260702","pageSize":1,"acts":[1]} |
200, SyncResult |
| AS-02 |
syncer 未配置 |
(TiDB 未配置时) |
503, {"error":"conversion syncer is not configured"} |
| AS-03 |
百度无数据 |
{"date":"20260101","pageSize":1} |
200, fetched=0 |
3.4.3 手动触发回调重试
| 项目 |
说明 |
| 端点 |
POST /admin/callbacks/retry |
| Content-Type |
application/json |
测试用例:
| 编号 |
场景 |
请求体 |
预期结果 |
| AR-01 |
正常重试 |
{"limit":10} |
200, RetryResult |
| AR-02 |
retryService 未配置 |
(TiDB 未配置时) |
503, {"error":"callback retryer is not configured"} |
| AR-03 |
limit=0(使用默认值) |
{"limit":0} |
200, RetryResult |
| AR-04 |
无待重试记录 |
{"limit":10} |
200, {"fetched":0,"sent":0,"failed":0} |
四、核心业务逻辑测试
4.1 竞价价格编码 (AuctionPriceEncoder)
| 编号 |
模式 |
输入 |
预期 |
| PE-01 |
none |
price=1000 |
URL encode 的 "1000" |
| PE-02 |
aes-ecb |
price=1000,eKey=16字节 |
Base64 编码的 AES-ECB 加密值(URL encoded) |
| PE-03 |
aes-cbc |
price=1000,eKey+iKey |
Base64 编码的 AES-CBC 加密值(URL encoded) |
| PE-04 |
aes-cbc iKey 不足16字节 |
eKey=xxx, iKey=short |
抛出 IllegalArgumentException |
| PE-05 |
未知模式 |
mode="unknown" |
抛出 IllegalArgumentException |
| PE-06 |
自动推断(有 eKey+iKey) |
mode="",提供 eKey+iKey |
使用 aes-cbc |
| PE-07 |
自动推断(仅 eKey) |
mode="",仅提供 eKey |
使用 aes-ecb |
| PE-08 |
自动推断(无 key) |
mode="",无 key |
使用 none |
4.2 百度转化签名 (ConversionClient)
| 编号 |
场景 |
验证 |
| CS-01 |
签名正确性 |
md5(timestamp + secret + randomStr) 结果为32位十六进制 |
| CS-02 |
相同输入产生相同签名 |
固定 timestamp/secret/randomStr 验证一致性 |
| CS-03 |
随机字符串唯一性 |
两次 newRandomString() 结果不同 |
4.3 MediaPlacement 解析
| 编号 |
场景 |
输入 params |
预期结果 |
| MP-01 |
指定 baidu_tag_id(匹配 platform 配置) |
{baidu_tag_id: "tag1"} |
Resolved(platform, appId, "tag1") |
| MP-02 |
指定 platform=android |
{platform: "android"} |
Resolved("android", androidAppId, androidTagId) |
| MP-03 |
指定 platform=ios |
{platform: "ios"} |
Resolved("ios", iosAppId, iosTagId) |
| MP-04 |
platform 别名("安卓") |
{platform: "安卓"} |
归一化为 "android" |
| MP-05 |
platform 别名("1"=ios) |
{platform: "1"} |
归一化为 "ios" |
| MP-06 |
无 tag/platform 但有默认值 |
{} |
使用默认 baiduAppId/baiduTagId |
| MP-07 |
多 tagId 未指定具体 tag |
{platform: "android"}(配置多个 tagId) |
抛出 IllegalArgumentException |
| MP-08 |
未知 tag_id |
{baidu_tag_id: "unknown"} |
抛出 IllegalArgumentException |
4.4 腾讯 Act 映射 (TencentClient)
| 编号 |
百度 Act |
预期腾讯 ActionType |
| AM-01 |
1 |
ACTIVATE_APP |
| AM-02 |
2 |
PURCHASE |
| AM-03 |
3 |
REGISTER |
| AM-04 |
4 |
ONE_DAY_RETENTION |
| AM-05 |
5 |
COMPLETE_ORDER |
| AM-06 |
6 |
START_APP |
| AM-07 |
7 |
CUSTOM (custom_action=key_behavior) |
| AM-08 |
8 |
CUSTOM (custom_action=7day_retention) |
| AM-09 |
9 |
CUSTOM (custom_action=3day_retention) |
| AM-10 |
99(未映射) |
抛出 IllegalArgumentException |
4.5 设备标识 MD5 处理 (TencentClient.ensureMd5)
| 编号 |
输入 |
预期 |
| MD-01 |
已是32位十六进制 "abcdef1234" |
原值(小写化) |
| MD-02 |
原始 IMEI "123456789012345" |
计算 MD5 |
| MD-03 |
null |
null |
| MD-04 |
空字符串 |
null |
| MD-05 |
大写32位十六进制 |
转小写返回 |
五、数据存储测试
5.1 Redis 热存储 (RedisHotStore)
| 编号 |
场景 |
操作 |
验证 |
| RH-01 |
记录 Bid |
recordBid(record) |
1. adx:tencent:bid:{qk} 存在 2. adx:tencent:media:tencent:{traceId} 存在 3. TTL=24h 4. Stream 有 type=bid 事件 |
| RH-02 |
按 qk 查找 Bid |
findBidByQk(qk) |
返回正确的 BidRecord |
| RH-03 |
按 mediaTrace 查找 Bid |
findBidByMediaTrace("tencent", traceId) |
返回正确的 BidRecord |
| RH-04 |
查找不存在的 Bid |
findBidByQk("nonexist") |
返回 null |
| RH-05 |
Bid TTL 过期 |
等待 TTL 后查询 |
返回 null |
| RH-06 |
记录 Tracking |
recordTracking(record) |
Stream 有 type=tracking 事件 |
| RH-07 |
确保消费者组 |
ensureGroup("test-group") |
不抛异常,幂等 |
| RH-08 |
读取 Stream 消息 |
read(group, consumer, 10) |
返回待消费的事件列表 |
| RH-09 |
ACK 消息 |
ack(group, ids) |
消息从 pending 列表移除 |
| RH-10 |
Trim Stream |
trim(maxLen) |
Stream 长度不超过 maxLen |
| RH-11 |
ClaimStale |
模拟超时未 ACK 消息 |
claimStale 能获取到超时消息 |
5.2 TiDB 冷存储 (TiDBColdStore)
| 编号 |
场景 |
操作 |
验证 |
| TC-01 |
自动建表 |
migrate() |
4张表创建成功 |
| TC-02 |
保存 Bid(新记录) |
saveBid(record) |
ad_bid_events 表有记录 |
| TC-03 |
保存 Bid(重复 qk) |
两次 saveBid(sameQk) |
更新而非报错(UPSERT) |
| TC-04 |
qk 为空抛异常 |
saveBid(qk=null) |
抛出 IllegalArgumentException |
| TC-05 |
保存 Tracking |
saveTracking(record) |
tracking_reports 表有记录 |
| TC-06 |
保存 Conversion(新记录) |
saveConversion(record) |
baidu_conversions 表有记录 |
| TC-07 |
保存 Conversion(重复 dedupeKey) |
两次相同 dedupeKey |
更新而非报错 |
| TC-08 |
保存 MediaCallback |
saveMediaCallback(record) |
media_callbacks 表有记录 |
| TC-09 |
查询成功回调存在 |
successfulCallbackExists(key) |
有 ok=1 记录返回 true |
| TC-10 |
查询成功回调不存在 |
successfulCallbackExists(key) |
无 ok=1 记录返回 false |
| TC-11 |
查询待重试回调 |
pendingMediaCallbacks("tencent", 10) |
返回 ok=0 且无对应 ok=1 的记录 |
| TC-12 |
空 dedupeKey 不查询 |
successfulCallbackExists("") |
返回 false |
六、后台任务测试
6.1 ColdWorker(冷路径数据持久化)
| 编号 |
场景 |
验证 |
| CW-01 |
正常消费 bid 事件 |
Stream 中 bid 事件被消费,TiDB ad_bid_events 有新记录 |
| CW-02 |
正常消费 tracking 事件 |
Stream 中 tracking 事件被消费,TiDB tracking_reports 有新记录 |
| CW-03 |
未知事件类型 |
Stream 中有 type=unknown 事件 → 抛异常,该批次不 ACK |
| CW-04 |
TiDB 写入失败 |
模拟 TiDB 不可用 → 抛异常,消息不 ACK(可重试) |
| CW-05 |
空 Stream |
无消息时返回 0 |
| CW-06 |
超时消息重新领取 |
模拟消费者崩溃 → 超过 pendingIdle 后被其他 worker claim |
| CW-07 |
Stream Trim |
消费后 Stream 长度被裁剪 |
6.2 ConversionSyncRunner(转化同步)
| 编号 |
场景 |
验证 |
| SR-01 |
正常同步(有匹配的 tencent bid) |
fetched > 0, matched > 0, sent > 0 |
| SR-02 |
无匹配 bid |
fetched > 0, skipped > 0, matched=0 |
| SR-03 |
bid 不属于 tencent |
记录到 baidu_conversions 但 skipped |
| SR-04 |
幂等 - 已成功发送过 |
alreadySent > 0,不重复调用腾讯 |
| SR-05 |
腾讯回传失败 |
failed > 0,media_callbacks 记录 ok=0 |
| SR-06 |
分页拉取多页 |
正确遍历多页数据 |
| SR-07 |
最大页数限制(100页) |
超过100页时停止 |
| SR-08 |
dateOffsetDays 配置 |
offset=0 查当天,offset=-1 查昨天 |
6.3 RetryService(回调重试)
| 编号 |
场景 |
验证 |
| RS-01 |
正常重试成功 |
fetched > 0, sent > 0, media_callbacks 新增 ok=1 记录 |
| RS-02 |
重试仍失败 |
failed > 0, attempt 递增, 新记录 ok=0 |
| RS-03 |
无待重试记录 |
fetched=0, sent=0, failed=0 |
| RS-04 |
使用默认 limit |
limit=0 时使用配置的默认值 |
| RS-05 |
网络异常 |
failed > 0, errorMessage 记录异常信息 |
6.4 Leader Election(分布式选举)
| 编号 |
场景 |
验证 |
| LE-01 |
单实例获取锁 |
成功获取锁并执行任务 |
| LE-02 |
多实例竞选 |
仅一个实例获得锁,其他等待 |
| LE-03 |
锁续约成功 |
任务执行期间锁不过期 |
| LE-04 |
续约失败(锁丢失) |
jobStop.isStopped() = true,任务停止 |
| LE-05 |
任务完成释放锁 |
任务结束后其他实例可获得锁 |
| LE-06 |
外部停止信号 |
stopped=true 时退出循环 |
| LE-07 |
skip-leader-election=true |
跳过选举直接运行任务 |
七、异常处理测试
7.1 全局异常处理器 (GlobalExceptionHandler)
| 编号 |
异常类型 |
预期 HTTP 状态码 |
预期响应格式 |
| EH-01 |
ResponseStatusException(400, "bad") |
400 |
{"error":"bad"} |
| EH-02 |
ResponseStatusException(503, "unavailable") |
503 |
{"error":"unavailable"} |
| EH-03 |
IllegalArgumentException("invalid param") |
400 |
{"error":"invalid param"} |
| EH-04 |
IOException("timeout") |
502 |
{"error":"timeout"} |
| EH-05 |
InterruptedException |
502 |
{"error":"..."} |
| EH-06 |
RuntimeException("unexpected") |
502 |
{"error":"unexpected"} |
| EH-07 |
NullPointerException(message=null) |
502 |
{"error":"internal error"} |
八、数据库表结构验证
8.1 ad_bid_events
| 字段 |
类型 |
约束 |
验证 |
| qk |
VARCHAR(128) |
UNIQUE NOT NULL |
唯一键,重复插入应更新 |
| media |
VARCHAR(64) |
- |
值为 "tencent" |
| media_trace_id |
VARCHAR(255) |
索引 |
与 media 联合索引 |
| req_id |
VARCHAR(512) |
- |
竞价请求 ID |
| price |
BIGINT UNSIGNED |
- |
竞价价格(分) |
| show_urls |
JSON |
- |
JSON 数组 |
| click_urls |
JSON |
- |
JSON 数组 |
| created_at |
TIMESTAMP(3) |
索引 |
毫秒精度 |
8.2 tracking_reports
| 字段 |
类型 |
约束 |
验证 |
| qk |
VARCHAR(128) |
联合索引 |
关联 bid |
| kind |
VARCHAR(32) |
NOT NULL |
"impression" 或 "click" |
| ok |
TINYINT(1) |
NOT NULL |
0 或 1 |
| tracking_url |
TEXT |
NOT NULL |
上报的 URL |
8.3 baidu_conversions
| 字段 |
类型 |
约束 |
验证 |
| dedupe_key |
VARCHAR(255) |
UNIQUE |
幂等键,格式: {media}:{qk}:{date}:{deviceId}:{act} |
| act |
INT |
联合索引 |
百度行为类型码 |
| payment |
DOUBLE |
- |
支付金额 |
8.4 media_callbacks
| 字段 |
类型 |
约束 |
验证 |
| dedupe_key |
VARCHAR(255) |
索引 |
回调去重键 |
| ok |
TINYINT(1) |
NOT NULL |
回传是否成功 |
| attempt |
INT |
DEFAULT 1 |
重试次数递增 |
| event_type |
INT |
NOT NULL |
对应百度 act |
| error_message |
TEXT |
- |
失败时记录错误信息 |
九、端到端集成测试
9.1 完整曝光 → 点击 → 转化回传流程
步骤 1: 发送曝光请求
GET /tencent/impression?click_id=e2e_test_001&platform=android&oaid=test_oaid_123
验证:
✓ 返回 204
✓ Redis 存在 bid 缓存
✓ Redis Stream 有 bid 事件
步骤 2: 发送点击请求
GET /tencent/click?click_id=e2e_test_001&platform=android&oaid=test_oaid_123
验证:
✓ 返回 302 重定向
✓ Redis Stream 有 click tracking 事件
步骤 3: 等待 ColdWorker 消费
验证:
✓ ad_bid_events 表有记录
✓ tracking_reports 表有 impression 和 click 记录
步骤 4: 触发转化同步
POST /admin/conversions/sync
Body: {"date":"20260702","pageSize":1,"acts":[1]}
验证:
✓ 百度转化数据被拉取
✓ 匹配到腾讯 bid 后回传成功
✓ baidu_conversions 表有记录
✓ media_callbacks 表有 ok=1 的记录
步骤 5: 幂等验证 - 再次同步
POST /admin/conversions/sync (相同参数)
验证:
✓ alreadySent > 0,不重复回传
9.2 回调失败 → 自动重试流程
步骤 1: 模拟腾讯回传失败
构造一条 media_callbacks 记录 (ok=0, attempt=1)
步骤 2: 触发回调重试
POST /admin/callbacks/retry
Body: {"limit":10}
验证:
✓ 获取到待重试记录
✓ 重试后生成新的 callback 记录
✓ attempt = 2
十、性能与压力测试
10.1 API 性能基线
| 接口 |
目标 QPS |
目标 P99 延迟 |
备注 |
| GET /health |
>10000 |
<10ms |
无外部依赖 |
| GET /tencent/impression |
>500 |
<200ms |
含百度竞价+Redis 写入 |
| GET /tencent/click |
>500 |
<200ms |
含 Redis 读取+百度上报 |
10.2 后台任务性能
| 任务 |
指标 |
目标 |
| ColdWorker |
消费速率 |
>1000 events/s |
| ConversionSync |
处理速率 |
>100 records/batch(并发=10) |
| RetryService |
重试速率 |
>50 records/batch |
10.3 Redis 压力
- bid 缓存 key 数量: 验证 TTL 自动清理
- Stream 长度: 验证 XTRIM 保持在配置的 maxLen 以内
- 内存使用: 监控 Redis 内存占用稳定性
十一、安全测试
| 编号 |
场景 |
验证 |
| SEC-01 |
百度签名校验 |
MD5 签名格式正确、不可伪造 |
| SEC-02 |
Access Token 保护 |
生产环境 token 从环境变量注入,不硬编码 |
| SEC-03 |
Redis 锁安全性 |
Lua 脚本保证仅持有者能释放/续约 |
| SEC-04 |
SQL 注入防护 |
MyBatis 参数化查询,无 SQL 拼接 |
| SEC-05 |
设备标识脱敏 |
腾讯回传使用 MD5 哈希而非明文 |
十二、配置测试
| 编号 |
场景 |
验证 |
| CFG-01 |
dev 环境启动 |
skip-leader-election=true,sync/retry 禁用 |
| CFG-02 |
test 环境启动 |
sync/retry 启用,短间隔 |
| CFG-03 |
prod 环境启动 |
环境变量注入,leader election 启用 |
| CFG-04 |
TiDB 未配置 |
ColdStore=null,相关功能降级但不崩溃 |
| CFG-05 |
Redis 连接失败 |
启动失败,打印明确错误信息 |
| CFG-06 |
百度 ADX endpoint 为空 |
竞价时抛 IllegalStateException |
| CFG-07 |
bid TTL 配置 |
默认 24h,可自定义 |
十三、测试执行方式
单元测试(推荐 Mock)
# 运行全部测试
mvn test -Ptest
# 运行指定类
mvn test -Dtest=AuctionPriceEncoderTest
# 运行指定方法
mvn test -Dtest=MediaPlacementTest#testResolvePlatformAndroid
集成测试(需要外部依赖)
# 需要 Redis + MySQL 环境
mvn verify -Ptest -Dspring.profiles.active=test
手动接口测试(cURL)
# 健康检查
curl -s http://localhost:8787/health
# 曝光监测
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8787/tencent/impression?click_id=test001&platform=android&oaid=test_oaid"
# 点击监测
curl -s -o /dev/null -w "%{http_code}" -L \
"http://localhost:8787/tencent/click?click_id=test001&platform=android"
# 查询转化
curl -s -X POST http://localhost:8787/admin/conversions/query \
-H "Content-Type: application/json" \
-d '{"date":"20260702","pageSize":1,"acts":[1,2]}'
# 触发同步
curl -s -X POST http://localhost:8787/admin/conversions/sync \
-H "Content-Type: application/json" \
-d '{"date":"20260702","pageSize":1,"acts":[1]}'
# 触发重试
curl -s -X POST http://localhost:8787/admin/callbacks/retry \
-H "Content-Type: application/json" \
-d '{"limit":10}'
十四、测试覆盖率目标
| 模块 |
目标覆盖率 |
重点 |
| httpapi (Controller) |
≥80% |
参数校验、异常处理 |
| baidu (AdxClient, ConversionClient) |
≥75% |
签名、加密、HTTP 调用 |
| tencent (TencentClient) |
≥80% |
act 映射、设备标识处理、回传逻辑 |
| conversionsync |
≥85% |
核心业务逻辑 |
| storage (Redis/TiDB) |
≥70% |
CRUD、幂等性 |
| leader |
≥60% |
锁获取/释放/续约 |
| worker |
≥75% |
事件消费、错误处理 |
十五、已知限制与注意事项
- 重试限制:RetryService 当前实现中,重试使用原始 callbackUrl 发送空 body,正式环境需验证腾讯 API 是否接受此方式
- 并发安全:ConversionSyncService 使用 10 并发线程处理支付记录,需确保 Redis/TiDB 连接池够用
- 时钟依赖:转化同步的
dateOffsetDays 依赖系统时钟,需确保服务器时间同步
- 百度 ADX 模拟:单元测试需 Mock 百度 ADX HTTP 响应(推荐 WireMock 或 MockWebServer)
- 数据清理:集成测试后需清理测试数据,避免影响后续测试
- Adm 字段拼写:百度原始字段
landdingPage(双 d),需注意 JSON 序列化/反序列化一致性