@umacloud/knowledge 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/00-governance/knowledge-map.md +1 -1
- package/agentic-delivery/01-standards/context-engineering-for-delivery.md +94 -0
- package/agentic-delivery/01-standards/eval-driven-delivery.md +90 -0
- package/agentic-delivery/01-standards/generated-code-failure-modes.md +91 -0
- package/agentic-delivery/01-standards/production-readiness-scorecard.md +79 -0
- package/agentic-delivery/01-standards/self-improving-memory-and-regression-sets.md +80 -0
- package/agentic-delivery/01-standards/spec-as-contract.md +88 -0
- package/agentic-delivery/01-standards/test-discipline-for-generated-code.md +94 -0
- package/agentic-delivery/01-standards/test-integrity-and-anti-gaming.md +92 -0
- package/agentic-delivery/01-standards/verifier-critic-pattern.md +89 -0
- package/ai/agent-evaluation-benchmark.md +1 -1
- package/ai/ai-agent-memory-context-management.md +1 -1
- package/ai/ai-cost-capacity-optimization-playbook.md +1 -1
- package/ai/ai-data-security-and-compliance-playbook.md +1 -1
- package/ai/ai-domain-index-and-checklist.md +1 -1
- package/ai/ai-governance-maturity-model.md +1 -1
- package/ai/ai-model-selection-and-routing-strategy.md +1 -1
- package/ai/ai-observability-and-oncall-runbook.md +1 -1
- package/ai/ai-rag-engineering-playbook.md +1 -1
- package/ai/ai-red-team-and-safety-evaluation.md +1 -1
- package/ai/ai-release-readiness-and-rollback-gate.md +1 -1
- package/ai/llm-agent-engineering-deep-dive.md +1 -1
- package/ai/prompt-and-tool-guardrails.md +1 -1
- package/api/01-standards/api-versioning-and-deprecation-policy.md +100 -0
- package/architecture/01-standards/configuration-and-environment-management.md +104 -0
- package/architecture/01-standards/domain-driven-design-complete.md +105 -0
- package/architecture/02-playbooks/migration-playbook.md +1 -1
- package/architecture/02-playbooks/system-design-playbook.md +1 -1
- package/architecture/adr-template-and-examples.md +1 -1
- package/architecture/configuration-management.md +95 -1158
- package/architecture/resilience-and-disaster-patterns.md +87 -27
- package/architecture/system-architecture-deep-dive.md +1 -1
- package/backend/01-standards/dependency-and-supply-chain-hygiene.md +90 -0
- package/backend/01-standards/error-handling-taxonomy.md +88 -0
- package/backend/01-standards/idempotency-and-safe-retries.md +101 -0
- package/backend/01-standards/message-queue-patterns.md +96 -374
- package/backend/01-standards/queue-and-consumer-reliability.md +98 -0
- package/backend/01-standards/resilience-and-fault-tolerance.md +101 -0
- package/backend/01-standards/transactions-and-concurrency-control.md +92 -0
- package/cicd/cicd-blueprint-deep-dive.md +1 -1
- package/cicd/release-readiness-gate.md +78 -27
- package/cloud-native/01-standards/container-security.md +1 -1
- package/cloud-native/01-standards/kubernetes-complete.md +1 -1
- package/cloud-native/02-playbooks/gitops-with-argocd.md +1 -1
- package/cloud-native/02-playbooks/k8s-troubleshooting-playbook.md +1 -1
- package/cloud-native/02-playbooks/multicloud-governance.md +1 -1
- package/cloud-native/02-playbooks/serverless-patterns.md +1 -1
- package/cloud-native/02-playbooks/service-mesh-playbook.md +1 -1
- package/cloud-native/03-checklists/container-security-checklist.md +1 -1
- package/cloud-native/03-checklists/k8s-production-readiness-checklist.md +1 -1
- package/cloud-native/04-antipatterns/container-antipatterns.md +1 -1
- package/cloud-native/04-antipatterns/k8s-antipatterns.md +1 -1
- package/cloud-native/05-cases/case-k8s-migration.md +1 -1
- package/cloud-native/05-cases/case-k8s-scaling.md +1 -1
- package/cloud-native/05-cases/case-k8s-security-incident.md +1 -1
- package/cloud-native/06-glossary/cloud-native-glossary.md +1 -1
- package/compliance/01-standards/audit-logging-and-evidence.md +111 -0
- package/compliance/01-standards/privacy-and-compliance-readiness.md +119 -0
- package/data/data-governance-and-modeling-deep-dive.md +1 -1
- package/design/ux-system-deep-dive.md +1 -1
- package/development/00-governance/document-template.md +1 -1
- package/development/01-standards/code-review-and-pr-hygiene.md +85 -0
- package/development/03-checklists/production-readiness-checklist.md +6 -6
- package/development/09-maturity/quarterly-audit-template.md +1 -1
- package/development/11-ui-excellence/ui-aesthetic-system.md +1 -1
- package/development/13-implementation-assets/knowledge-gates-execution.md +1 -1
- package/development/api-contract-and-versioning-guide.md +1 -1
- package/development/api-governance-complete.md +1 -1
- package/development/backend-engineering-complete.md +1 -1
- package/development/code-review-quality-complete.md +11 -34
- package/development/concurrency-reliability-complete.md +1 -1
- package/development/database-engineering-complete.md +1 -1
- package/development/engineering-effectiveness-complete.md +1 -1
- package/development/engineering-standards-deep-dive.md +1 -1
- package/development/frontend-engineering-complete.md +1 -1
- package/development/performance-capacity-complete.md +1 -1
- package/development/refactor-migration-complete.md +1 -1
- package/development/refactoring-and-techdebt-playbook.md +1 -1
- package/development/security-in-development-complete.md +1 -1
- package/experts/architect/contract-first-api-design.md +140 -0
- package/experts/product-manager/prd-template-and-structure.md +144 -0
- package/experts/product-manager/requirements-engineering-ears.md +133 -0
- package/experts/qa-lead/test-plan-template.md +127 -0
- package/frontend/01-standards/accessibility-acceptance-gate.md +91 -0
- package/frontend/01-standards/accessibility-complete.md +3 -3
- package/frontend/01-standards/ui-states-and-resilient-data-fetching.md +97 -0
- package/high-quality-engineering-playbook.md +1 -1
- package/incident/02-playbooks/chaos-engineering-playbook.md +1 -1
- package/incident/postmortem-and-response-deep-dive.md +1 -1
- package/mobile/01-standards/flutter-complete.md +5 -5
- package/mobile/01-standards/react-native-complete.md +5 -5
- package/mobile/02-playbooks/mobile-performance.md +6 -6
- package/mobile/03-checklists/mobile-release-checklist.md +2 -2
- package/mobile/04-antipatterns/mobile-antipatterns.md +2 -2
- package/observability/01-standards/observability-and-slo-operations.md +88 -0
- package/observability/01-standards/observability-standards.md +2 -0
- package/operations/01-standards/cost-and-finops-engineering.md +84 -0
- package/operations/01-standards/production-readiness-review.md +103 -0
- package/operations/aiops-anomaly-detection.md +1 -1
- package/operations/capacity-planning.md +1 -1
- package/operations/chaos-engineering.md +1 -1
- package/operations/incident-command-system.md +1 -1
- package/operations/observability-complete.md +1 -1
- package/operations/slo-sli-playbook.md +1 -1
- package/operations/sre-operations-deep-dive.md +1 -1
- package/package.json +1 -1
- package/performance/01-standards/performance-budgets-and-load-testing.md +91 -0
- package/product/feature-prioritization-framework.md +1 -1
- package/product/kpi-and-metric-tree.md +1 -1
- package/product/product-discovery-and-prd-deep-dive.md +1 -1
- package/release-engineering/01-standards/feature-flag-lifecycle.md +92 -0
- package/release-engineering/01-standards/progressive-delivery-and-release.md +92 -0
- package/release-engineering/02-playbooks/release-rollback-and-recovery-playbook.md +99 -0
- package/release-engineering/03-checklists/release-rollback-readiness-checklist.md +61 -0
- package/release-engineering/04-antipatterns/release-antipatterns.md +63 -0
- package/security/01-standards/authorization-and-access-control.md +94 -0
- package/security/02-playbooks/incident-response-security-playbook.md +1 -1
- package/security/02-playbooks/penetration-testing-playbook.md +1 -1
- package/security/security-architecture-deep-dive.md +1 -1
- package/security/threat-modeling-stride-playbook.md +1 -1
- package/testing/01-standards/ci-test-gates-and-coverage.md +93 -0
- package/testing/01-standards/contract-testing-and-api-contracts.md +102 -0
- package/testing/01-standards/test-data-and-ephemeral-environments.md +105 -0
- package/testing/02-playbooks/e2e-testing-playbook.md +1 -1
- package/testing/risk-based-test-matrix.md +1 -1
- package/testing/testing-strategy-deep-dive.md +1 -1
|
@@ -1,37 +1,97 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: resilience-and-disaster-patterns
|
|
3
|
-
title:
|
|
3
|
+
title: 架构级韧性与容灾规范(故障域/多活拓扑/RPO-RTO/备份可恢复/容灾演练,商业级必读)
|
|
4
4
|
domain: architecture
|
|
5
|
-
category:
|
|
6
|
-
difficulty:
|
|
7
|
-
tags: [
|
|
8
|
-
quality_score:
|
|
9
|
-
last_updated: 2026-06-
|
|
5
|
+
category: 01-standards
|
|
6
|
+
difficulty: advanced
|
|
7
|
+
tags: [resilience, disaster-recovery, dr, blast-radius, failure-domain, multi-region, active-active, active-passive, rpo, rto, replication, backup-restore, failover, dr-drill, cell-based, graceful-degradation, 韧性, 容灾, 故障域, 多活, 备份恢复, 容灾演练, 商业级]
|
|
8
|
+
quality_score: 95
|
|
9
|
+
last_updated: 2026-06-29
|
|
10
10
|
---
|
|
11
|
-
#
|
|
11
|
+
# 架构级韧性与容灾规范(商业级必读)
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
> 代码级韧性讲"每一次外部调用怎么写才不会被拖垮"(超时/重试/熔断/舱壁/背压,见 `backend/01-standards/resilience-and-fault-tolerance`)。本规范讲**上一层**:整个机房挂了、整个区域不可用、一个核心依赖整体瘫痪、数据被误删/勒索加密时,系统能不能在可接受的时间内、可接受的数据损失内**恢复服务**。
|
|
14
|
+
> 商业级系统不假设"机房不会挂",而是预先划好故障域、控制爆炸半径、定好 RPO/RTO、做可验证的备份、并**定期真演练**容灾切换。备份做了但从没恢复过、容灾方案写在文档里从没切过——这两条是容灾事故的头号原因。
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
- 保障核心业务在故障、流量抖动、依赖异常时仍可维持可控服务水平。
|
|
16
|
+
## 1. 故障域与爆炸半径(设计的出发点)
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
- 超时控制:所有外部调用必须有超时上限。
|
|
20
|
-
- 重试策略:仅对可重试错误启用指数退避。
|
|
21
|
-
- 熔断机制:失败率超过阈值自动进入熔断。
|
|
22
|
-
- 限流降级:保护核心链路,非关键功能降级。
|
|
23
|
-
- 隔离舱:关键资源池隔离,避免级联故障。
|
|
18
|
+
韧性架构的第一性问题是:**一个组件/一个区域出事,会波及多大范围?**
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
20
|
+
- **划清故障域**:进程、主机、可用区、区域、云账户/供应商各是一层独立故障域。关键服务跨**可用区**部署,重要系统跨**区域**具备容灾能力。
|
|
21
|
+
- **控制爆炸半径**:让单点故障的影响**局部化**。手段包括单元化(cell-based)架构、分片隔离(shuffle sharding)、按租户/区域切分,使一个单元的故障只影响其内用户,不是全量。
|
|
22
|
+
- **消除单点(SPOF)**:任一单一组件故障不得导致整体不可用;冗余覆盖到无状态服务、有状态存储、网络入口、依赖中间件。
|
|
23
|
+
- **依赖关键性分级**:盘点每个依赖,标注"它挂了影响什么、是否核心链路"。核心与非核心依赖隔离,非核心故障可降级(见 §6),不拖垮核心。
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
- 每季度执行一次故障注入演练。
|
|
32
|
-
- 每半年执行一次跨区容灾切换演练。
|
|
33
|
-
- 演练必须输出发现问题、修复计划与责任人。
|
|
25
|
+
## 2. 多区域拓扑(按 RTO 与成本取舍)
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
| 拓扑 | 含义 | RTO/RPO | 成本/复杂度 | 适用 |
|
|
28
|
+
|---|---|---|---|---|
|
|
29
|
+
| 单区多可用区 | 同区跨 AZ 冗余 | AZ 故障近秒级 | 低 | 多数业务基线 |
|
|
30
|
+
| 主备(active-passive,冷/温/热) | 备区待命,主区故障切过去 | 分钟~小时(取决冷/温/热) | 中 | 有区域级容灾要求 |
|
|
31
|
+
| 多活(active-active) | 多区域同时服务、互为备份 | 近秒级、对用户近无感 | 高(数据一致性最难) | 高可用核心系统 |
|
|
32
|
+
|
|
33
|
+
要点:**先定业务能容忍的 RTO/RPO,再选拓扑**,不要为"高大上"上多活却扛不住其数据一致性复杂度。备区必须**周期性接真流量验证**(哪怕小比例),否则"温备"实为"死备"——真要切时才发现起不来。
|
|
34
|
+
|
|
35
|
+
## 3. RPO 与 RTO(把容灾目标量化)
|
|
36
|
+
|
|
37
|
+
- **RPO(恢复点目标)**:能容忍丢多少数据(时间窗)。RPO=0 要求同步复制(牺牲延迟/吞吐);RPO=5 分钟可用异步复制。按数据重要性分级设定,不要一刀切。
|
|
38
|
+
- **RTO(恢复时间目标)**:从故障到恢复服务允许多久。RTO 决定拓扑(热备/多活才有分钟级以下 RTO)与是否需要自动化切换。
|
|
39
|
+
- **分级而非全局**:核心交易数据 RPO/RTO 严苛,日志/分析类可宽松。为每类关键数据/服务明确 RPO/RTO 并**实测验证**达成,而非纸面承诺。
|
|
40
|
+
- **目标驱动投入**:RPO/RTO 越严,成本越高。让业务在"恢复保障"与"成本"间做明确权衡,而不是工程一厢情愿。
|
|
41
|
+
|
|
42
|
+
## 4. 数据复制与一致性
|
|
43
|
+
|
|
44
|
+
容灾的难点几乎都在**有状态数据**:
|
|
45
|
+
|
|
46
|
+
- **同步 vs 异步复制**:同步复制 RPO≈0 但增加写延迟、跨区时影响吞吐;异步复制低延迟但故障时丢最近未复制数据。按 RPO 选择,常按数据分级混用。
|
|
47
|
+
- **故障切换的数据问题**:切到备区后,主区"复活"可能带来**脑裂**与数据冲突。预先设计:谁是权威、回切流程、冲突如何收敛(版本/时间戳/业务规则)。
|
|
48
|
+
- **多活的写冲突**:多区域同时可写必须解决冲突(分区路由让同一实体只在一区写、或 CRDT/末写胜+业务合并)。回避不了就别轻易上多活双写。
|
|
49
|
+
- **备份独立于主存储**:备份要放在与主数据**不同故障域/不同账户**,防止区域级故障或勒索同时毁掉主数据与备份。
|
|
50
|
+
|
|
51
|
+
## 5. 备份与可恢复性(备份的价值在于"能恢复")
|
|
52
|
+
|
|
53
|
+
备份本身没有价值,**能在 RTO 内恢复出正确数据**才有价值。
|
|
54
|
+
|
|
55
|
+
- **备份策略成体系**:全量 + 增量组合,周期与保留期可审计;关键数据满足其 RPO。
|
|
56
|
+
- **3 份/异地/离线意识**:多副本、跨地域、至少一份**离线/不可变**(防勒索软件加密或误删波及在线备份)。
|
|
57
|
+
- **恢复必须演练**:定期从备份**真实恢复**到隔离环境并校验数据完整与可用,测出真实恢复耗时(对照 RTO)。**从未验证的备份等于没有备份。**
|
|
58
|
+
- **覆盖误操作与逻辑损坏**:不仅防硬件/区域故障,也要能从"误删表、错误迁移、数据被污染"中按时间点恢复(PITR)。
|
|
59
|
+
- **配置与基础设施也要可重建**:不只业务数据,IaC、配置、密钥引用也要能重建,否则数据恢复了环境却起不来(见 `architecture/01-standards/configuration-and-environment-management`)。
|
|
60
|
+
|
|
61
|
+
## 6. 故障切换与系统级降级
|
|
62
|
+
|
|
63
|
+
- **切换要自动且可演练**:关键路径的故障检测与切换尽量自动化(健康探测 + 流量切换),并有清晰 runbook;手动步骤最小化且被演练过。
|
|
64
|
+
- **回切同样重要**:切过去之后怎么安全切回来(数据回灌、一致性校验)要预先设计,别只想着切出去。
|
|
65
|
+
- **系统级优雅降级**:区域/依赖故障时,整体能退化到**核心可用**(只读模式、缓存兜底、关闭非核心功能、排队而非拒绝),而不是全站 502。降级是有契约的设计,不是临时拍。
|
|
66
|
+
- **依赖故障预案**:对每个核心依赖预设"它整体不可用时怎么办"(降级/切备/排队),写进 runbook。
|
|
67
|
+
|
|
68
|
+
## 7. 容灾演练(没演练过的方案 = 不存在的方案)
|
|
69
|
+
|
|
70
|
+
- **定期故障注入**:周期性主动注入故障(杀实例、断 AZ、断依赖),验证自动恢复与降级真的生效(方法见 `incident/02-playbooks/chaos-engineering-playbook`、`operations/chaos-engineering`)。
|
|
71
|
+
- **区域级容灾切换演练**:周期性真实演练跨区切换 + 回切,测 RTO/RPO 实际达成,而非纸面。
|
|
72
|
+
- **备份恢复演练**:周期性从备份实恢复并校验(见 §5)。
|
|
73
|
+
- **演练必有产出**:每次演练输出发现的问题、修复计划、责任人与期限,闭环跟踪;演练结论反哺架构与 runbook。
|
|
74
|
+
- **纳入就绪审查**:"备份验证过、容灾切换演练过、RPO/RTO 达标"是生产就绪审查的硬项(见 `operations/01-standards/production-readiness-review`)。
|
|
75
|
+
|
|
76
|
+
## 8. 反模式(出现即不合格)
|
|
77
|
+
|
|
78
|
+
1. **假设机房/区域不会挂**:无跨 AZ/跨区冗余,单点故障即全站不可用。
|
|
79
|
+
2. **备份从未验证恢复**:以为有备份,真要恢复时恢复不出来或超 RTO。
|
|
80
|
+
3. **容灾方案只在文档里**:从没真切过,首切即在事故现场试错。
|
|
81
|
+
4. **备份与主数据同故障域**:区域故障或勒索同时毁掉主数据与备份。
|
|
82
|
+
5. **只防硬件故障**:无法从误删/逻辑损坏/数据污染按时间点恢复。
|
|
83
|
+
6. **RPO/RTO 全局一刀切**:不分级,要么过度投入要么核心数据保护不足。
|
|
84
|
+
7. **熔断/降级缺系统级兜底**:区域故障时整站崩,而非退化到核心可用。
|
|
85
|
+
8. **多活双写不解决冲突**:脑裂与写冲突导致数据错乱,比停服更糟。
|
|
86
|
+
9. **切得出去回不来**:无回切设计,故障恢复后长期跑在降级/备用态。
|
|
87
|
+
|
|
88
|
+
## 9. 最低交付 checklist
|
|
89
|
+
|
|
90
|
+
- [ ] 划清故障域,关键服务跨 AZ、重要系统跨区;控制爆炸半径,消除 SPOF。
|
|
91
|
+
- [ ] 依赖按关键性分级,核心/非核心隔离,非核心可降级不拖垮核心。
|
|
92
|
+
- [ ] 为每类关键数据/服务定明确 RPO/RTO 并实测达成,拓扑按目标选取。
|
|
93
|
+
- [ ] 复制策略按 RPO 选(同步/异步混用);预设故障切换的脑裂/冲突收敛与回切流程。
|
|
94
|
+
- [ ] 备份成体系(全量+增量、跨地域、至少一份离线/不可变),覆盖误删与逻辑损坏(PITR)。
|
|
95
|
+
- [ ] 定期从备份真实恢复并校验,实测恢复耗时对照 RTO;配置/IaC/密钥可重建。
|
|
96
|
+
- [ ] 故障切换尽量自动 + runbook + 回切设计;系统级优雅降级有契约。
|
|
97
|
+
- [ ] 定期故障注入与跨区切换演练,每次输出问题/修复/责任人并闭环;纳入生产就绪审查。
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dependency-and-supply-chain-hygiene
|
|
3
|
+
title: 依赖与供应链卫生规范(锁定/更新节奏/SBOM/漏洞分诊,产品团队商业级必读)
|
|
4
|
+
domain: backend
|
|
5
|
+
category: 01-standards
|
|
6
|
+
difficulty: advanced
|
|
7
|
+
tags: [dependency, supply-chain, lockfile, sbom, provenance, vulnerability-triage, update-cadence, transitive-dependency, license, renovate, 依赖管理, 供应链, 锁文件, 漏洞分诊, 更新节奏, 产物清单, 商业级]
|
|
8
|
+
quality_score: 95
|
|
9
|
+
last_updated: 2026-06-29
|
|
10
|
+
---
|
|
11
|
+
# 依赖与供应链卫生规范(产品团队商业级必读)
|
|
12
|
+
|
|
13
|
+
> 现代应用 80% 以上的代码不是你写的,是你的依赖、以及依赖的依赖。每引入一个包,你就把自己产品的安全与稳定性,托付给了一群你从没见过的维护者。
|
|
14
|
+
> 这份规范不是给安全团队的攻防手册(那部分见 `security/01-standards/supply-chain-security`、`security/supply-chain-security`),而是给**做产品的工程团队**的日常纪律:怎么选依赖、怎么锁、多久更新一次、漏洞来了多快必须处理、怎么证明"我们装的就是我们以为的东西"。把供应链卫生当成**持续的运营工作**,而不是上线前补一次扫描。
|
|
15
|
+
|
|
16
|
+
## 1. 引入一个依赖前的准入
|
|
17
|
+
|
|
18
|
+
加一个依赖是一个**长期负债**决定,不是 `add` 一下那么轻:
|
|
19
|
+
|
|
20
|
+
- **先问要不要**:能用标准库 / 已有依赖几十行解决的,不要为此引入一个大树。每个依赖都带来传递依赖、漏洞面、升级负担。
|
|
21
|
+
- **评估健康度**:维护是否活跃、有没有在修安全问题、发布是否规律、单一维护者还是有组织、下载与采用规模、传递依赖体量、许可证是否可用。一次性小工具尤其警惕。
|
|
22
|
+
- **警惕仿冒**:包名与流行包高度相似(拼写仿冒)、刚发布不久、下载量极低却出现在依赖里——可能是仿冒/混淆攻击,引入前核对来源。
|
|
23
|
+
- **锁定来源**:内部包用组织 scope/命名空间,配置内部仓库优先,防止公共仓库同名包被优先解析(依赖混淆)。
|
|
24
|
+
|
|
25
|
+
## 2. 锁定:装的就是你以为的
|
|
26
|
+
|
|
27
|
+
- **必须有锁文件**:每个项目都有锁文件并**提交版本库**,锁定**全部**依赖(含传递依赖)的精确版本。"只锁直接依赖"等于没锁——攻击与破坏性变更大多来自传递层。
|
|
28
|
+
- **锁文件带完整性校验**:锁文件应包含哈希/完整性摘要,安装时校验,保证下载到的产物字节级一致(防中间篡改与仓库投毒)。
|
|
29
|
+
- **CI 用锁文件做可复现安装**:CI/构建用"严格按锁文件安装"的命令(不允许隐式升级),保证构建可复现;锁文件变更必须随 PR 一起评审。
|
|
30
|
+
- **锁文件 diff 要被看见**:依赖升级的锁文件 diff 进入代码评审视野,新增/跳变的传递依赖能被注意到,而不是无人看的几千行变更。
|
|
31
|
+
|
|
32
|
+
## 3. 更新节奏:与其攒大版本,不如小步常更
|
|
33
|
+
|
|
34
|
+
不更新和乱更新都是错的。攒着不更,等到出 0-day 才被迫一次性跨多个大版本,风险与工作量都爆炸。
|
|
35
|
+
|
|
36
|
+
| 更新类型 | 建议节奏 | 处理方式 |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| 安全补丁 | 立即(按分诊 SLA) | 优先合入,单独发布 |
|
|
39
|
+
| 补丁/次版本 | 每周/每两周批量 | 自动化 PR + 测试通过即合 |
|
|
40
|
+
| 主版本(破坏性) | 计划性、单独处理 | 读迁移说明、单独 PR、充分回归 |
|
|
41
|
+
| 已弃用/无维护依赖 | 主动排期替换 | 列入技术债,定替换计划 |
|
|
42
|
+
|
|
43
|
+
- **自动化更新 PR**:用自动化机器人(依赖更新 bot)持续开升级 PR,配合 CI 测试,把"更新"变成低摩擦的日常,而不是季度性大扫除。
|
|
44
|
+
- **分组与限流**:把低风险更新分组合并,限制同时打开的 PR 数,避免淹没评审。
|
|
45
|
+
- **更新有测试护栏**:依赖升级必须跑全量测试 + 关键路径回归后才合,杜绝"升级即合"导致悄悄破功能。
|
|
46
|
+
|
|
47
|
+
## 4. SBOM 与可追溯(provenance)
|
|
48
|
+
|
|
49
|
+
- **每次发布生成 SBOM**:构建产出软件物料清单(标准格式),完整列出制品包含的所有组件与版本,存入制品仓库随版本归档。
|
|
50
|
+
- **SBOM 是持续资产不是一次性文件**:新漏洞披露时,用历史 SBOM 反查"我们哪些线上版本受影响",而不是临时去翻每个服务的依赖。
|
|
51
|
+
- **出处可证明**:能证明制品由可信流水线、从可信源码、用锁定的依赖构建而来(构建出处/签名)。生产部署侧校验制品来源与完整性,拒绝来路不明的产物。
|
|
52
|
+
- **依赖与制品绑定**:每个发布版本能精确回答"用了哪些依赖的哪些版本",出事可定位影响范围。
|
|
53
|
+
|
|
54
|
+
## 5. 漏洞分诊:有 SLA,不是看到就慌、看不到就拖
|
|
55
|
+
|
|
56
|
+
扫描器会报一堆,**关键是分诊**——按真实风险定优先级和处理时限,而不是被 CVSS 数字牵着走。
|
|
57
|
+
|
|
58
|
+
- **持续扫描**:CI 中集成依赖漏洞扫描;并**定时**对已发布版本重扫(今天没漏洞的依赖明天可能被披露)。
|
|
59
|
+
- **按可达性 + 严重度分诊**:同一个 CVE,在你产品里**是否真的可达/可利用**(在调用路径上吗?是 dev 依赖吗?输入可控吗?)决定真实风险。结合严重度与可达性定级,避免对不可达漏洞过度反应、对可达漏洞低估。
|
|
60
|
+
- **明确处理 SLA**:给每个等级定响应时限(例:可利用的严重漏洞按小时计、高危按天计、中低危排期)。SLA 写进规范并被度量。
|
|
61
|
+
- **处置方式**:升级修复版本优先;无修复版本时评估临时缓解(关闭受影响功能/加防护/降级);确认不可达可记录**带理由和到期日的例外**,到期复审,绝不无限期忽略。
|
|
62
|
+
- **CI 阻断要分级**:对"可达的高危/严重"阻断构建;对噪音类降级为告警,避免一刀切让团队学会绕过门禁。
|
|
63
|
+
|
|
64
|
+
## 6. 许可证与合规卫生
|
|
65
|
+
|
|
66
|
+
- **许可证可见**:知道每个(含传递)依赖的许可证;CI 检查是否引入与产品分发模式冲突的许可证(如对闭源产品引入强 copyleft)。
|
|
67
|
+
- **禁用清单**:维护不允许的许可证清单,新增依赖触发即阻断或人工审批。
|
|
68
|
+
- **可向客户提供清单**:商业合规场景下能提供组件与许可证清单(SBOM 复用)。
|
|
69
|
+
|
|
70
|
+
## 7. 反模式(出现即不合格)
|
|
71
|
+
|
|
72
|
+
1. **没有锁文件 / 只锁直接依赖**:构建不可复现,传递依赖随时漂移、可被投毒。
|
|
73
|
+
2. **攒着不更新**:依赖长期不动,出 0-day 才被迫跨多个大版本紧急升级。
|
|
74
|
+
3. **升级即合不测试**:依赖 PR 不跑回归就合,悄悄破坏功能。
|
|
75
|
+
4. **扫描噪音 + 一刀切阻断**:不分诊、不看可达性,门禁噪音大到团队学会绕过。
|
|
76
|
+
5. **看到漏洞无 SLA**:处理全凭心情,可利用的严重漏洞拖几周。
|
|
77
|
+
6. **只上线前扫一次**:不对已发布版本持续重扫,新披露漏洞无人发现。
|
|
78
|
+
7. **dev 依赖无人管**:以为开发期依赖不影响产品,忽视其漏洞与投毒风险。
|
|
79
|
+
8. **来路不明的制品直接上线**:不校验出处与完整性,无 SBOM,出事查不出影响范围。
|
|
80
|
+
|
|
81
|
+
## 8. 最低交付 checklist
|
|
82
|
+
|
|
83
|
+
- [ ] 引入依赖前评估健康度/维护性/许可证/传递体量,警惕仿冒与混淆。
|
|
84
|
+
- [ ] 每个项目有锁文件并入库,锁定全部(含传递)依赖 + 完整性校验;CI 严格按锁文件可复现安装。
|
|
85
|
+
- [ ] 自动化更新 PR + 测试护栏,小步常更;主版本计划性单独处理;弃用依赖列技术债排期替换。
|
|
86
|
+
- [ ] 每次发布生成并归档 SBOM,可用历史 SBOM 反查受影响线上版本。
|
|
87
|
+
- [ ] 制品出处可证明,生产侧校验来源与完整性,依赖与发布版本绑定可追溯。
|
|
88
|
+
- [ ] CI 集成漏洞扫描 + 对已发布版本定时重扫;按可达性+严重度分诊,分级处理有 SLA。
|
|
89
|
+
- [ ] 漏洞例外须带理由与到期日并复审;可达的严重漏洞阻断发布。
|
|
90
|
+
- [ ] 许可证可见、有禁用清单、可按需输出组件与许可证清单。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: error-handling-taxonomy
|
|
3
|
+
title: 错误处理分类与用户可见错误契约(商业级必读)
|
|
4
|
+
domain: backend
|
|
5
|
+
category: 01-standards
|
|
6
|
+
difficulty: intermediate
|
|
7
|
+
tags: [error-handling, taxonomy, operational-error, programmer-error, user-error, retryable, fail-fast, error-contract, user-facing, i18n, 错误处理, 错误分类, 错误契约, 商业级]
|
|
8
|
+
quality_score: 95
|
|
9
|
+
last_updated: 2026-06-29
|
|
10
|
+
---
|
|
11
|
+
# 错误处理分类与用户可见错误契约(商业级必读)
|
|
12
|
+
|
|
13
|
+
> "出错就 try/catch 打条日志返回 500"是业余做法。商业级系统先把错误**分类**——这是 bug 还是预期内的故障?能不能重试?该不该让用户看到?——再据此决定**快速失败、重试、降级,还是向用户解释**。
|
|
14
|
+
> HTTP 错误信封(见 `backend/01-standards/api-and-error-conventions`)解决"错误长什么样";本规范解决更上游的问题:**如何对错误分类,以及给最终用户看什么**。
|
|
15
|
+
|
|
16
|
+
## 1. 第一刀:可预期 vs 不可预期
|
|
17
|
+
|
|
18
|
+
| 类别 | 含义 | 处理方式 |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **操作性错误(operational)**| 正确程序在运行时遇到的**预期内**异常:网络超时、依赖不可用、输入非法、余额不足、限流 | 预先设计好如何处理:校验、重试、降级、向用户解释 |
|
|
21
|
+
| **程序性错误(programmer / bug)**| 代码缺陷:空指针、类型错、断言失败、不该到达的分支 | **不要吞**。让它快速失败、记录、告警、修复——重试或掩盖只会掩埋 bug |
|
|
22
|
+
|
|
23
|
+
这一刀是基础:操作性错误要**优雅处理**,程序性错误要**快速暴露**。把 bug 当操作性错误吞掉("catch 一切返回默认值")是最常见的腐化源——故障被静默,数据被悄悄写坏。
|
|
24
|
+
|
|
25
|
+
## 2. 第二刀:按来源与责任分类
|
|
26
|
+
|
|
27
|
+
| 类型 | 例子 | 状态码倾向 | 给用户看 |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| 用户错误(user error)| 表单非法、缺字段、格式错 | 4xx(422/400)| **要**:明确告诉哪里错、怎么改 |
|
|
30
|
+
| 鉴权/授权错误 | 未登录、无权限 | 401 / 403 | 要:提示登录或无权,但不泄露资源是否存在 |
|
|
31
|
+
| 业务规则拒绝 | 库存不足、状态不允许、超额 | 409 / 422 | 要:说明业务原因(可执行)|
|
|
32
|
+
| 资源不存在 | 找不到 | 404 | 要:简洁提示 |
|
|
33
|
+
| 限流 | 触发速率限制 | 429 | 要:提示稍后重试(可给 Retry-After)|
|
|
34
|
+
| 依赖故障(下游)| 第三方/数据库挂 | 503 / 502 | **泛化**:暂不可用,请稍后;不暴露内部 |
|
|
35
|
+
| 内部缺陷(bug)| 未捕获异常 | 500 | **泛化**:通用错误 + request_id;绝不暴露栈/SQL |
|
|
36
|
+
|
|
37
|
+
原则:**4xx 是调用方的问题(可指明并指导),5xx 是我们的问题(对用户泛化,对自己详细记录 + 告警)。**
|
|
38
|
+
|
|
39
|
+
## 3. 第三刀:可重试 vs 终止性
|
|
40
|
+
|
|
41
|
+
- **可重试(transient)**:超时、连接失败、5xx/服务不可用、限流——配合指数退避 + 抖动 + 重试预算可重试(见 `backend/01-standards/resilience-and-fault-tolerance`)。
|
|
42
|
+
- **终止性(permanent)**:4xx 参数错、鉴权失败、业务拒绝——**重试也白搭**,还放大压力;直接返回,让调用方修正。
|
|
43
|
+
- 在错误类型/错误码上**显式标注**可否重试,让调用方和重试中间件能据此决策,而不是猜。
|
|
44
|
+
|
|
45
|
+
## 4. 用户可见错误契约(user-facing error contract)
|
|
46
|
+
|
|
47
|
+
给最终用户的错误信息是产品体验的一部分,不是技术副产物。一条合格的用户错误信息:
|
|
48
|
+
|
|
49
|
+
| 要素 | 要求 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| 说人话 | 不暴露栈、SQL、内部码、英文异常名;用用户能懂的语言 |
|
|
52
|
+
| 可执行 | 告诉用户**下一步怎么办**(改什么、稍后重试、联系支持)|
|
|
53
|
+
| 不吓人、不甩锅 | 系统侧故障别让用户觉得是自己错了 |
|
|
54
|
+
| 不泄密 | 不暴露内部结构、是否存在某资源、为何鉴权失败的细节 |
|
|
55
|
+
| 可定位 | 携带 `request_id`/支持码,用户报障时工程师能据此查到那条日志/审计 |
|
|
56
|
+
| 可国际化 | 文案走 i18n,按 `code` 渲染,不在代码里硬编码某语言句子 |
|
|
57
|
+
|
|
58
|
+
机器可读 + 人类可读分离:接口返回**稳定的机器码**(`INSUFFICIENT_STOCK`)+ 文案;前端按 `code` 分支处理与本地化,**不靠 message 文案做逻辑**(文案会变、会翻译)。
|
|
59
|
+
|
|
60
|
+
## 5. 分层处理职责
|
|
61
|
+
|
|
62
|
+
- **边界校验**:在入口(API 层)校验输入,非法即 422 + 字段错误,别让脏数据流进核心。
|
|
63
|
+
- **集中映射**:一个统一的错误处理器/过滤器把内部异常映射成对外错误信封,**不在每个 controller 重复 try/catch**。
|
|
64
|
+
- **保留上下文**:异常向上传递时保留原因链(cause),别 catch 后只 `throw new Error("failed")` 丢掉根因。
|
|
65
|
+
- **区分日志级别**:用户错误/业务拒绝 → INFO/WARN(这是正常流程,不是事故);bug/依赖故障 → ERROR + 告警。别把每个 422 都打成 ERROR 淹没真问题。
|
|
66
|
+
- **失败要可观测**:错误带 `request_id`、错误码、关键上下文进结构化日志,便于聚合定位(见 `observability/`)。
|
|
67
|
+
|
|
68
|
+
## 6. 反模式(出现即不合格)
|
|
69
|
+
|
|
70
|
+
1. **吞异常**:`catch` 后什么都不做 / 返回默认值,把 bug 和故障静默掉。
|
|
71
|
+
2. **一律 500 或一律 200**:所有错误都 500,或业务失败回 200 再在 body 塞 `success:false`。
|
|
72
|
+
3. **向用户泄露内部**:把栈、SQL、内部路径、异常类名直接抛到前端。
|
|
73
|
+
4. **吓人/无指引文案**:"Error" / "Something went wrong" 没有下一步。
|
|
74
|
+
5. **靠 message 做逻辑**:前端用文案字符串匹配判断错误类型(一改文案/一翻译就崩)。
|
|
75
|
+
6. **该 fail-fast 却重试**:对 bug 或终止性错误反复重试,掩埋问题、放大压力。
|
|
76
|
+
7. **丢根因**:层层 catch-rethrow 把原始原因链丢光,线上无法定位。
|
|
77
|
+
8. **422 当 ERROR 刷屏**:正常的用户输入错误被打成 ERROR,把日志淹没、把告警拖疲。
|
|
78
|
+
|
|
79
|
+
## 7. 最低交付 checklist
|
|
80
|
+
|
|
81
|
+
- [ ] 区分操作性错误(优雅处理)与程序性 bug(快速失败 + 告警,绝不吞)。
|
|
82
|
+
- [ ] 按来源分类映射到正确状态码:4xx 调用方问题、5xx 我方问题。
|
|
83
|
+
- [ ] 错误显式标注可重试/终止性,配合重试预算使用。
|
|
84
|
+
- [ ] 对用户:泛化内部故障、不泄露内部、给可执行下一步、带 request_id。
|
|
85
|
+
- [ ] 返回稳定机器码 + i18n 文案,前端按 code 分支,不靠 message。
|
|
86
|
+
- [ ] 输入边界校验 + 集中错误映射,不在各处重复 try/catch。
|
|
87
|
+
- [ ] 异常保留原因链;按类型分日志级别,bug/依赖故障告警。
|
|
88
|
+
- [ ] 错误进结构化日志,可聚合、可按 request_id 定位。
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: idempotency-and-safe-retries
|
|
3
|
+
title: 幂等性与安全重试规范(商业级后端必读)
|
|
4
|
+
domain: backend
|
|
5
|
+
category: 01-standards
|
|
6
|
+
difficulty: intermediate
|
|
7
|
+
tags: [idempotency, retry, exactly-once, deduplication, outbox, concurrency, 幂等, 重试, 商业级]
|
|
8
|
+
quality_score: 95
|
|
9
|
+
last_updated: 2026-06-29
|
|
10
|
+
---
|
|
11
|
+
# 幂等性与安全重试规范(商业级后端必读)
|
|
12
|
+
|
|
13
|
+
> 网络会超时、客户端会重试、消息队列会重投——任何一次写操作都可能被执行**不止一次**。
|
|
14
|
+
> 商业级后端必须保证"重复执行不产生重复副作用":一次下单不能扣两次款,一条消息不能发两遍。
|
|
15
|
+
> 不做幂等的写接口,在生产里一定会出资损或脏数据。
|
|
16
|
+
|
|
17
|
+
## 1. 核心定义
|
|
18
|
+
|
|
19
|
+
- **幂等(idempotent)**:同一请求执行一次和执行多次,对系统状态的影响**相同**。读、`PUT` 全量替换、`DELETE` 天然幂等;`POST` 创建/扣款**默认不幂等**,必须人为做成幂等。
|
|
20
|
+
- **安全重试**:客户端/调用方在不确定上一次是否成功时,可以**放心重试**而不会造成第二次副作用。
|
|
21
|
+
- **投递语义**:分布式下"恰好一次(exactly-once)投递"几乎不可达;现实是"至少一次(at-least-once)投递 + 消费端幂等 = 有效恰好一次(effectively-once)处理"。
|
|
22
|
+
|
|
23
|
+
## 2. 哪些操作必须做幂等
|
|
24
|
+
|
|
25
|
+
| 操作 | 是否需要幂等 | 原因 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| 创建订单 / 支付 / 扣款 / 退款 | 必须 | 重复=资损 |
|
|
28
|
+
| 发短信/邮件/推送/通知 | 必须 | 重复=骚扰用户 |
|
|
29
|
+
| 扣减库存 / 发放优惠券/积分 | 必须 | 重复=超卖/多发 |
|
|
30
|
+
| 消费 MQ 消息(任意业务) | 必须 | 队列至少一次投递 |
|
|
31
|
+
| Webhook 回调处理 | 必须 | 上游会重投 |
|
|
32
|
+
| 纯查询 / 全量替换 PUT | 天然幂等 | 无累积副作用 |
|
|
33
|
+
|
|
34
|
+
## 3. 幂等键(Idempotency Key)——首选方案
|
|
35
|
+
|
|
36
|
+
让**调用方生成**一个唯一键(UUID/业务单号),随请求传入(`Idempotency-Key` 头或请求体字段)。服务端用它去重:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
1. 收到请求,取出幂等键 K。
|
|
40
|
+
2. 在去重存储里以 K 为唯一约束尝试占位(INSERT ... ON CONFLICT / SETNX)。
|
|
41
|
+
3. 占位成功(首次)→ 执行业务,把"结果"与 K 一起持久化,返回结果。
|
|
42
|
+
4. 占位失败(重复)→ 不再执行业务,直接返回上次已保存的结果(同样的状态码与响应体)。
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
要点:
|
|
46
|
+
- 幂等键要带**作用域**:通常 `(用户/租户, 业务类型, K)` 组合唯一,避免跨业务撞键。
|
|
47
|
+
- 去重记录要**存结果**,重复请求要返回**与首次一致**的响应(含相同的 `201/200` 与 body),而不是报错。
|
|
48
|
+
- 给去重记录设 **TTL**(如 24h~7d),匹配业务"可能重试的窗口",避免无限增长。
|
|
49
|
+
- "占位"和"业务写"要么在**同一事务**里,要么用"先占位(pending)→执行→标记(done)"的状态机,并处理"占位了但业务还没跑完又来一次"的并发(见 §5)。
|
|
50
|
+
|
|
51
|
+
## 4. 没有幂等键时的去重手段
|
|
52
|
+
|
|
53
|
+
调用方无法传键时,用**业务自然唯一性**兜底:
|
|
54
|
+
|
|
55
|
+
- **唯一约束**:在 DB 上对业务唯一维度建唯一索引(如 `(order_no)`、`(user_id, idempotency_scope, day)`),重复插入直接被 DB 拒绝(捕获唯一冲突当作"已处理")。这是最可靠的最后一道防线——**不要只靠"先查再插"**(查与插之间有竞态)。
|
|
56
|
+
- **去重表 / 去重缓存**:以"消息ID/事件ID/请求指纹"为键记录已处理,消费前先查。缓存去重要接受偶发漏判,**关键资损场景必须落 DB 唯一约束**。
|
|
57
|
+
- **状态机前置校验**:只允许从合法前态流转(`pending → paid`),重复的"支付成功"在 `paid` 态下变成无副作用的空操作。
|
|
58
|
+
|
|
59
|
+
## 5. 并发与"进行中"的重复
|
|
60
|
+
|
|
61
|
+
重复请求可能**几乎同时**到达,"先查后写"会双双查到"没处理过"然后都执行。必须用以下之一根除竞态:
|
|
62
|
+
|
|
63
|
+
- **DB 唯一约束**:让数据库串行化,第二个插入失败。
|
|
64
|
+
- **占位即加锁**:插入一条 `status=processing` 的去重记录(唯一键),第二个请求插入失败→说明"有人正在处理",返回 409/稍后重试或等待首个结果。
|
|
65
|
+
- **乐观锁(版本号/CAS)**:`UPDATE ... SET version=version+1 WHERE id=? AND version=?`,影响行数为 0 说明已被改过,放弃或重读重试。
|
|
66
|
+
- **悲观锁 / 分布式锁**:`SELECT ... FOR UPDATE` 或带 TTL 的分布式锁,锁的粒度要小、要有超时、要可重入安全。分布式锁必须配合**栅栏令牌(fencing token)**或 DB 唯一约束兜底,因为锁会因 GC/超时被两个持有者同时认为自己持有。
|
|
67
|
+
|
|
68
|
+
## 6. 安全重试的客户端侧
|
|
69
|
+
|
|
70
|
+
- 只对**幂等操作**自动重试;非幂等操作重试前必须先变幂等(带幂等键)。
|
|
71
|
+
- 重试用**指数退避 + 抖动(jitter)**,设最大次数与总时限,避免重试风暴打垮下游(参见 `architecture/resilience-and-disaster-patterns`)。
|
|
72
|
+
- 区分错误:`408/429/5xx/网络超时`可重试;`4xx`(除 429)是请求本身的问题,**不要重试**。
|
|
73
|
+
- 超时不等于失败:超时后状态**未知**,必须靠幂等键安全重试来确认,而不是盲目再发一笔。
|
|
74
|
+
|
|
75
|
+
## 7. 消息与跨服务:Outbox + 消费端幂等
|
|
76
|
+
|
|
77
|
+
异步链路要保证"本地状态变更"与"对外消息"原子一致,且消费端不重复处理:
|
|
78
|
+
|
|
79
|
+
- **事务发件箱(Outbox)**:在同一本地事务里写业务表 + 写一条 outbox 消息;独立投递器再把 outbox 发到 MQ。避免"DB 提交了但消息没发"或"消息发了但 DB 回滚了"的双写不一致。
|
|
80
|
+
- **消费端去重(Inbox)**:消费者以"消息ID/事件ID"为唯一键记录已处理,重复投递被去重表挡掉。
|
|
81
|
+
- 结论:**生产端至少一次 + 消费端幂等 = 有效恰好一次**。不要追求传输层的"恰好一次"。
|
|
82
|
+
|
|
83
|
+
## 8. 反模式(出现即不合格)
|
|
84
|
+
|
|
85
|
+
1. **写接口不幂等**:`POST /pay` 重复调用扣两次款。
|
|
86
|
+
2. **只靠"先查再插"去重**:查与插之间有竞态,并发下双写。
|
|
87
|
+
3. **幂等键无 TTL / 无作用域**:存储无限增长,或跨业务撞键。
|
|
88
|
+
4. **重复请求报错而非回放结果**:客户端重试拿到 409 后无法判断到底成没成。
|
|
89
|
+
5. **对非幂等操作自动重试**:超时即重发,制造重复副作用。
|
|
90
|
+
6. **重试无退避无上限**:下游抖动时把它彻底打死(重试风暴)。
|
|
91
|
+
7. **依赖分布式锁但无 DB 唯一兜底**:锁失效时两个持有者同时写。
|
|
92
|
+
|
|
93
|
+
## 9. 最低交付 checklist
|
|
94
|
+
|
|
95
|
+
- [ ] 所有"创建/扣款/发券/发通知/消费消息"类写操作都做了幂等。
|
|
96
|
+
- [ ] 资损相关路径有 **DB 唯一约束**作为最终防线,不只靠缓存/先查后插。
|
|
97
|
+
- [ ] 幂等键带作用域 + TTL,重复请求回放首次结果(状态码与 body 一致)。
|
|
98
|
+
- [ ] 并发重复用唯一约束/乐观锁/占位锁根除竞态,覆盖"进行中"重复。
|
|
99
|
+
- [ ] 客户端重试仅限幂等操作,带指数退避+抖动+上限,区分可重试错误。
|
|
100
|
+
- [ ] 跨服务用 Outbox 保双写一致 + 消费端 Inbox 去重。
|
|
101
|
+
- [ ] 有针对"重复提交/超时重试/消息重投"的自动化测试。
|