games-development-ai/docs/architecture/assets/05-失败降级补偿全景.svg
zizi f9d6baa5f4 docs(arch-atlas): 总图叙 apex 系统全景图说——第一期收口(导览式·7系统级图+七领域导航)
读一份文档完成整个系统了解+据图 review:§2 七张跨域系统级图(六域生命周期/六层分层/
现行SAA线‖远期tier2轨边界/跨域数据飞轮/失败降级补偿全景/端到端鉴权信任边界/角色×端)+
§3 领域导航(每域讲什么故事+最该据图review的命门缝+链接)+§4 按角色下钻路径。
单源只链不重画;6 SVG 经脚本核良构/零溢出/脚注转义;9 源档 commit hash 防漂移门;
现行vs远期严格标(tier2远期待spike虚线/Dify废/网关双校验未来态)。
第一期=总图叙+7域图说(运维/产品/架构/沙箱/后端/前端/运营)全收口。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:35:15 +00:00

136 lines
12 KiB
XML
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.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 880" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#334155"/></marker>
<marker id="arrowR" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#dc2626"/></marker>
<marker id="arrowB" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#64748b"/></marker>
<style>
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:13px;font-weight:600}
.flow{stroke:#334155;stroke-width:2;fill:none}.flowr{stroke:#dc2626;stroke-width:2;fill:none}
.flowb{stroke:#64748b;stroke-width:1.6;fill:none;stroke-dasharray:6 4}
.badge{font-size:10.5px;font-weight:700}
</style>
</defs>
<rect x="0" y="0" width="1480" height="880" fill="#f8fafc"/>
<text x="40" y="38" class="t h1">图 5 · 失败 / 降级 / 补偿路径全景</text>
<text x="40" y="58" class="mut sm">据图做评审最易发现"缝"的一张:横切外部模型 / 异步 / 支付三类不可控调用,把"超时 → 失败 → 重试 → 幂等 → 补偿 → 兜底"这条可靠性主线集中画出。可靠性是设计进去的,不是事后补的。</text>
<!-- 总纲条 -->
<rect x="40" y="76" width="1400" height="34" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="1.4"/>
<text x="52" y="98" class="xs t" font-weight="700">底线原则:</text>
<text x="128" y="98" class="xs mut">凡涉外部模型 / 异步任务 / 支付,必须考虑超时、失败、重试、幂等、补偿与兜底。降级方向要看清——有的可降 mock少算收入有的降级即吞真钱必须 fail-fast</text>
<!-- 三条横切链路 -->
<!-- 链路 A外部模型生成 -->
<rect x="40" y="124" width="1400" height="172" rx="12" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="56" y="148" class="t h2">链路 A · 外部模型调用(生成主线)</text>
<rect x="56" y="162" width="180" height="56" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.4"/>
<text x="66" y="182" class="xs t">调便宜 LLM</text>
<text x="66" y="200" class="xxs mut">P50&lt;60s · P95&lt;180s</text>
<text x="66" y="212" class="xxs mut">超时上界 120s</text>
<rect x="276" y="162" width="180" height="56" rx="8" fill="#fff7ed" stroke="#d97706" stroke-width="1.4"/>
<text x="286" y="182" class="xs t">超时 / 失败</text>
<text x="286" y="200" class="xxs mut">TIMED_OUT / FAILED</text>
<text x="286" y="212" class="xxs mut">状态机显式建边</text>
<rect x="496" y="162" width="180" height="56" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.4"/>
<text x="506" y="182" class="xs t">重试 / 救场阶梯</text>
<text x="506" y="200" class="xxs mut">FAILED≤2 · TIMED_OUT≤1</text>
<text x="506" y="212" class="xxs mut">repair→escalate 升档</text>
<rect x="716" y="162" width="180" height="56" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.4"/>
<text x="726" y="182" class="xs t">幂等</text>
<text x="726" y="200" class="xxs mut">idempotency_key</text>
<text x="726" y="212" class="xxs mut">Redis 5 分钟去重</text>
<rect x="936" y="162" width="200" height="56" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.4"/>
<text x="946" y="182" class="xs t">兜底:giveup 留证据</text>
<text x="946" y="200" class="xxs mut">超过重试 → 终态 FAILED</text>
<text x="946" y="212" class="xxs mut">宁可显式失败,不交付坏游戏</text>
<rect x="1156" y="162" width="266" height="56" rx="8" fill="#fee2e2" stroke="#dc2626" stroke-width="1.4"/>
<text x="1166" y="182" class="xs t" font-weight="700">真实风险(已发生)</text>
<text x="1166" y="200" class="xxs mut">2026-06 二厂系通道全废 → new-api</text>
<text x="1166" y="212" class="xxs mut">多通道健康巡检 + key 监控 + 批跑冻结阀</text>
<line x1="236" y1="190" x2="274" y2="190" class="flow" marker-end="url(#arrow)"/>
<line x1="456" y1="190" x2="494" y2="190" class="flowr" marker-end="url(#arrowR)"/>
<line x1="676" y1="190" x2="714" y2="190" class="flow" marker-end="url(#arrow)"/>
<line x1="896" y1="190" x2="934" y2="190" class="flow" marker-end="url(#arrow)"/>
<text x="56" y="244" class="xxs mut">配套:LLM 成本失控应对 = 限频限额 + 日预算熔断 + 显式 max_tokens,超额暂停生成入口、仅确定性兜底。</text>
<text x="56" y="262" class="xxs mut">沙箱侧失败降级:取包 / sha256 不过 / 超时 → 退 demo 兜底,只 console.warn、不上抛 error父级把 error 当致命态会隐藏宿主)——详见沙箱图说图 2/图 7。</text>
<text x="56" y="280" class="xxs t" font-weight="700">降级口径:生成 / 沙箱可降级(少一次成功生成,可接受)。</text>
<!-- 链路 B异步任务 / 跨表 -->
<rect x="40" y="308" width="1400" height="150" rx="12" fill="#fefce8" stroke="#ca8a04" stroke-width="1.8"/>
<text x="56" y="332" class="t h2">链路 B · 异步任务 / 跨表一致性</text>
<rect x="56" y="346" width="240" height="58" rx="8" fill="#fff" stroke="#ca8a04" stroke-width="1.4"/>
<text x="66" y="366" class="xs t">最终一致 + 补偿(非分布式事务)</text>
<text x="66" y="384" class="xxs mut">原则:尽量避免分布式事务</text>
<text x="66" y="398" class="xxs mut">改用最终一致 + 定时补偿</text>
<rect x="316" y="346" width="240" height="58" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.4"/>
<text x="326" y="366" class="xs t">唯一真原子发布(脊柱级)</text>
<text x="326" y="384" class="xxs mut">project 把 合规裁决 + 出包 + 入流</text>
<text x="326" y="398" class="xxs mut">串成一个事务,失败整体回滚</text>
<rect x="576" y="346" width="240" height="58" rx="8" fill="#fff" stroke="#ca8a04" stroke-width="1.4"/>
<text x="586" y="366" class="xs t">补偿 job 兜底</text>
<text x="586" y="384" class="xxs mut">定时扫"中间态超 5 分钟"记录</text>
<text x="586" y="398" class="xxs mut">三 XXL-Job + Feign 接缝驱动</text>
<rect x="836" y="346" width="240" height="58" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.4"/>
<text x="846" y="366" class="xs t">幂等四范式</text>
<text x="846" y="384" class="xxs mut">uk_biz_no / uk(trace+type) / uk_source</text>
<text x="846" y="398" class="xxs mut">/ 唯一键 + active 软开关</text>
<rect x="1096" y="346" width="326" height="58" rx="8" fill="#fff" stroke="#ca8a04" stroke-width="1.4"/>
<text x="1106" y="366" class="xs t">future-state 折算</text>
<text x="1116" y="384" class="xxs mut">RocketMQ / Nacos 未部署,异步派发现走进程内</text>
<text x="1116" y="398" class="xxs mut">telemetry 消费靠 uk_event_id 逐事件幂等防重</text>
<line x1="296" y1="375" x2="314" y2="375" class="flow" marker-end="url(#arrow)"/>
<line x1="556" y1="375" x2="574" y2="375" class="flow" marker-end="url(#arrow)"/>
<line x1="816" y1="375" x2="834" y2="375" class="flow" marker-end="url(#arrow)"/>
<text x="56" y="428" class="xxs mut">这五条业务链的关键 API 是否都在岗,由运维冒烟门按链分组点检(见运维图说图 4);API 全绿 ≠ UI 通,用户可见波次另做真 UI 走查。</text>
<text x="56" y="446" class="xxs t" font-weight="700">降级口径:发布走原子事务,半截状态绝不 commit——要么全成、要么全回滚。</text>
<!-- 链路 C支付 / 打款 -->
<rect x="40" y="470" width="1400" height="158" rx="12" fill="#fff7ed" stroke="#d97706" stroke-width="1.8"/>
<text x="56" y="494" class="t h2">链路 C · 支付 / 打款(钱的事 · 最严)</text>
<rect x="56" y="508" width="240" height="60" rx="8" fill="#fff" stroke="#d97706" stroke-width="1.4"/>
<text x="66" y="528" class="xs t">账户恒等式</text>
<text x="66" y="546" class="xxs mut">balance+frozen+total_withdraw</text>
<text x="66" y="560" class="xxs mut">= total_income 永远成立</text>
<rect x="316" y="508" width="240" height="60" rx="8" fill="#fee2e2" stroke="#dc2626" stroke-width="1.5"/>
<text x="326" y="528" class="xs t" font-weight="700">发起 ≠ 终态</text>
<text x="326" y="546" class="xxs mut">提现审核事务内只 CAS 0→1</text>
<text x="326" y="560" class="xxs mut">终态由回调驱动</text>
<rect x="576" y="508" width="240" height="60" rx="8" fill="#fff" stroke="#d97706" stroke-width="1.4"/>
<text x="586" y="528" class="xs t">双路驱动 + CAS</text>
<text x="586" y="546" class="xxs mut">正常路回调、异常路补偿 job</text>
<text x="586" y="560" class="xxs mut">两路都过 CAS,重复驱动安全</text>
<rect x="836" y="508" width="240" height="60" rx="8" fill="#fff" stroke="#d97706" stroke-width="1.4"/>
<text x="846" y="528" class="xs t">对账锚点链</text>
<text x="846" y="546" class="xxs mut">ad_revenue.id —source_ref→ income</text>
<text x="846" y="560" class="xxs mut">—余额→ account —→ transfer_ref</text>
<rect x="1096" y="508" width="326" height="60" rx="8" fill="#fee2e2" stroke="#dc2626" stroke-width="1.5"/>
<text x="1106" y="528" class="xs t" font-weight="700">打款渠道现 = mock 桩</text>
<text x="1116" y="546" class="xxs mut">PayoutClient 仅 MockPayoutClient,真 wxpay/alipay 被合规闸门阻塞</text>
<text x="1116" y="560" class="xxs mut">抽象已对,补真实现零改业务码切真</text>
<line x1="296" y1="538" x2="314" y2="538" class="flowr" marker-end="url(#arrowR)"/>
<line x1="556" y1="538" x2="574" y2="538" class="flow" marker-end="url(#arrow)"/>
<line x1="816" y1="538" x2="834" y2="538" class="flow" marker-end="url(#arrow)"/>
<rect x="56" y="578" width="1366" height="42" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="1.4"/>
<text x="66" y="598" class="xs t" font-weight="700">关键反差(评审必看):打款降级口径与生成 / 广告正好相反——</text>
<text x="66" y="614" class="xs mut">广告渠道缺失降级 mock 可接受(少算收入);但打款渠道缺失若降级 mock 就是吞真钱,必须 fail-fast、绝不发假钱。审核降级一律朝保守(阿里云超时降到 review、绝不降到 pass)。</text>
<!-- 横切三类的共性收口 -->
<rect x="40" y="640" width="1400" height="100" rx="12" fill="#f1f5f9" stroke="#475569" stroke-width="1.8"/>
<text x="56" y="664" class="t h2">三类横切链路的共性收口(据图 review 的检查清单)</text>
<text x="56" y="688" class="xs mut">① 每个外部 / 异步 / 资金动作是否都有幂等键? ② 失败 / 超时是否在状态机里显式建了边、而非吞掉? ③ 补偿 job 是否扫得到中间态?</text>
<text x="56" y="708" class="xs mut">④ 降级方向是否对(可降 mock vs 必须 fail-fast? ⑤ 抽象是否做对mock ↔ 真实现可零改业务码切换)? ⑥ 对账锚点链是否端到端串得起来?</text>
<text x="56" y="728" class="xxs t" font-weight="700">凡有一格答不上,就是一处"缝"——这正是这张系统级图存在的意义:让评审者据图就能定位可靠性裂缝,而不必逐文件翻。</text>
<!-- 图例 -->
<text x="40" y="772" class="t h2">图例:</text>
<line x1="120" y1="768" x2="170" y2="768" class="flow" marker-end="url(#arrow)"/><text x="178" y="772" class="t xs">正常推进</text>
<line x1="300" y1="768" x2="350" y2="768" class="flowr" marker-end="url(#arrowR)"/><text x="358" y="772" class="t xs">失败 / 资金红线分支</text>
<rect x="540" y="758" width="34" height="20" rx="5" fill="#fee2e2" stroke="#dc2626" stroke-width="1.5"/><text x="582" y="773" class="t xs">现状缺口 / mock 桩(诚实标)</text>
<g class="badge"><rect x="800" y="759" width="56" height="18" rx="3" fill="#16a34a"/><text x="805" y="772" fill="#fff">可靠</text>
<rect x="864" y="759" width="56" height="18" rx="3" fill="#dc2626"/><text x="869" y="772" fill="#fff">安全</text></g>
<text x="930" y="772" class="mut xs">幂等/补偿/恒等式=可靠 · 打款 fail-fast 不发假钱=安全</text>
<text x="40" y="810" class="mut xs">映射:architecture/架构/README §9 + .agents/rules/security-and-reliability + 运营/变现端到端 + 沙箱图说 状态:现(含 mock 桩诚实标)| 设计变动须同步本图</text>
</svg>