Files
huya-go/docs/seckill-optimization-roadmap.md
T
yml2213 908ceb0b3b docs(review): 沉淀 10.18 抢购实战复盘与对比优化路线图
- 新增 docs/seckill-analysis-20261018.md:覆盖 5 台机器 23 实例 562 账号全量指标剖析
- 新增 docs/seckill-optimization-roadmap.md:对标 dygou_go 形成四大工作包优化路线图
2026-10-18 21:23:45 +08:00

95 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# huya-go 全面架构深度分析与优化路线图(对比 dygou_go)
> **编制日期**:2026-10-18
> **基线版本**:huya-go v0.5.3
> **参考对标**:`/Users/yml/codes/dygou_go`(斗鱼自动化抢购系统)
> **实战支撑**:2026-10-18 5台机器 23实例 562账号实战日志
---
## 一、架构与功能全景对比矩阵
| 模块 / 维度 | `dygou_go`(斗鱼项目) | `huya-go`(虎牙现状) | 差距与优化潜力等级 |
|---|---|---|:---:|
| **1. 兑换请求超时控制** | 细粒度超短超时(秒级超时熔断,区分服务端超时与网络超时),单次请求绝不 hang 住 | 透传全局任务 `ctx`,底层网络超时为 10~15 秒;实战中曾出现账号被 hang 整整 5.07 秒 | 🔴 **高危 / 极高优先级** |
| **2. 错误分类与退避精度** | 细分 Transient / InFlight / RateLimited / Throttled / StockOut / Terminal;支付有专门退避阶梯 | 「账号未绑定!」被误判为 `CategorySessionLost`;`TooFrequent` 未纳入存活状态;退避阶梯较粗 | 🔴 **高危 / 极高优先级** |
| **3. 积分基线与刚性扣分对账** | `ScoreBaselineStore`(`scores.json`):抢购前建基线,抢购后自动比对 `余额差值 == 售价`,反查暗中成功单 | 仅抢购成功时单号异步刷新,无基线文件,无全局刚性对账能力,网络闪断或超时导致的暗中成交会漏单 | 🟡 **重要 / 高优先级** |
| **4. 作战战报持久化与导出** | `last_xiaodian_report.json` 保存战报,支持 GUI 一键导出 Excel / CSV,包含每账号、商品、耗时、状态 | 抢购战果仅保存在内存中,界面关闭或刷新即丢失,无 Excel / CSV 导出功能,代抢对账依赖翻日志 | 🟡 **重要 / 高优先级** |
| **5. 备选目标多级轮转 (Fallback)** | 允许配置主目标与备选目标,主目标一旦售罄(StockOut),未完成账号自动无缝切换到备选目标 | `RunTargets` 虽支持多目标,但采用同轮平铺探测,无“优先级与售罄自动降级”机制,GUI 仅能填单 PID | 🟡 **重要 / 高优先级** |
| **6. 成功战报精美长图生成** | 原生 `image/draw` + `freetype` 自动生成战报图片卡片(带标题、成功率、账号列表、耗时),支持一键发群晒单 | 无大图生成功能,用户只能手动截屏或拍照 | 🟢 **体验增强 / 中优先级** |
| **7. 跨实例同机协同错峰** | 跨平台互斥锁;支持实例级错峰参数,避免同机多开在 0.00s 齐射造成本地网卡与单 IP 限流 | 已做实例数据目录隔离,但同机多实例在 0.00s 同步发射,加剧单 IP 限流(10.18 pc-1 限流比达 60%) | 🟢 **微调优化 / 中优先级** |
---
## 二、四大优化工作包详细设计
### 📦 工作包 1:抢购引擎核心稳态升级(消灭卡死与误杀)
#### 1.1 单请求紧凑超时熔断(Per-Request Fast Timeout)
- **问题根源**:
在 `internal/sniper/exchange.go` 的 `exchangeTarget` 中,调用 `client.ScoreExchangePrize(ctx, ...)` 时直接透传了外部 `ctx`。底层 WSS/HTTP 连接的超时时间长达 10~15 秒。
10.18 实战日志证据:账号 `1199664503824` 与 `1199668733274` 在 loop 1 遭遇服务端微服务超时,单次请求足足耗时 **5.07 秒** 才返回 `biz exception:-7`,导致账号在黄金前 5 秒彻底停滞,直接错过抢购。
- **改进设计**:
引入秒杀专属请求超时 `RequestTimeout`(建议默认 `1500ms ~ 2000ms`):
```go
reqCtx, reqCancel := context.WithTimeout(ctx, cfg.RequestTimeout)
exchange, err := client.ScoreExchangePrize(reqCtx, account.UID, account.Cookie, sid, pid)
reqCancel()
```
若在 1.5 秒内未收到完整响应,立刻以超时错误返回并进入短退避重试,绝不阻塞当前账号的抢购节奏。
#### 1.2 剥离「账号未绑定!」分类,彻底解绑会话失效
- **问题根源**:
在 `internal/sniper/classify.go:116` 中,把「账号未绑定」归入 `CategorySessionLost`。
10.18 实战中出现 914 次该提示,实证表明:同一账号在遭遇数次「未绑定」后仍能成功抢到并扣分,这纯属虎牙下游和平精英角色服务超时降级。当前代码若连续遇到 8 次会直接永久判死(`account.done = true`),且界面上频频报警会误导用户。
- **改进设计**:
1. 引入独立分类 `CategoryRoleUnbound = "role_unbound"`(角色未绑定 / 服务抖动)。
2. `classifyExchangeText` 中,「账号未绑定/未绑定账号」映射到 `CategoryRoleUnbound`,真正的凭证失效(「请先登录/登录失效/token失效」)才保留为 `CategorySessionLost`。
3. `CategoryRoleUnbound` 仅触发普通业务重试退避(如 200~300ms),不计入连续会话失效判死阈值(`sessionStreak`)。
4. 在 `retry.go:179` 的 `sessionAliveCategory` 中补充 `CategoryTooFrequent`,只要服务端返回限流,说明账号凭证依然有效,避免 `sessionStreak` 在连续限流中虚假累积。
---
### 📦 工作包 2:积分基线与刚性对账体系(借鉴 dygou_go ScoreBaselineStore)
- **业务背景**:
抢购高并发下,常有边缘异常:客户端断网、RPC 超时、信封解析异常,但服务端其实已经扣除了积分并将礼包发放至背包。仅凭客户端是否收到 `category=success` 会发生严重漏单!
- **改进设计**:
1. 新增 `internal/sniper/score_baseline.go`(或 `internal/score/`):
- 数据文件:`scores.json`(保存在各实例的 `dataDir` 下)。
- 记录每个账号的基线积分及时间戳:`{"score": 1250, "at": 1729242000}`。
2. **基线更新时机**:
- 用户手动点击「查询积分」时批量更新并落盘。
- 导入/检查 Cookie 时自动更新。
3. **刚性对账(Verify / Reconcile)**:
- 抢购结束后(或用户随时点击「对账核对」):全量异步拉取一次所有账号的最新积分。
- 计算差值:`diff = baseline - current`。
- 若 `diff == target.Price`(或 `diff > 0`),即判定为“刚性扣分成功”,自动将原本标记为超时/未知的单子翻案为“成功”,补齐战报!
---
### 📦 工作包 3:战报持久化与 Excel / CSV 导出
- **业务背景**:
多账号操作、代抢代换必须给客户或管理员提供清晰的明细表格。当前版本任务一结束、窗口一关,明细就消失了,只能通过日志正则翻查,效率极低。
- **改进设计**:
1. 战报存储:每次抢购开始后,在实例数据目录下维护 `last_seckill_report.json`。
- 字段包含:`AccountUID`、`TargetPID`、`TargetName`、`Price`、`Status`(已抢到/售罄/限流/积分不足等)、`Attempts`、`FirstTime`、`SuccessTime`、`Duration`、`Msg`。
2. 导出功能(在 `internal/gui/app.go` 暴露 Wails 绑定方法):
- `ExportSeckillReportCSV() (string, error)`
- `ExportSeckillReportExcel() (string, error)`
3. 前端界面:
- 在作战表上方或「任务已结束」提示旁增加【导出战报】按钮,一键调出文件保存对话框。
---
### 📦 工作包 4:主备目标轮转(Priority Fallback)与售罄自动切换
- **业务背景**:
10.18 实战显示,最火爆的怪诞乔克(13433)在 10 秒即彻底售罄,而小黄鸭(13443)和天网(13435)在 15~20 秒依然有充沛库存。目前用户必须人工判断或多开不同实例去分别打。
- **改进设计**:
1. 支持配置主目标(Priority 1)与备选目标(Priority 2...)。
2. 在 `runAccountRound` 调度中:
- 默认只对主目标发起 `exchangeTarget`。
- 一旦主目标在当前实例被全量确认为售罄(`CategorySoldOut`),引擎自动标记主目标下线,账号无需停止,后续轮次立即自动无缝打向备选目标,把剩余的 20 秒窗口利用到底!