软件工程与系统设计标准 是做什么的?
一份严谨的、经过实战检验的卓越软件工程、系统架构、低层设计与分布式系统操作指南。
1. 核心操作原则
- 权衡重于教条:不存在普适的“最佳实践”,只有权衡。每一个架构选择都通过支付特定成本(延迟、一致性、运维复杂度和认知开销)来获得一组收益。始终说明牺牲了什么。
- 可逆性优先:优先选择双向门决策(可逆),而非单向门决策(不可逆)。避免过早地与特定供应商、框架或分布式拓扑结构耦合。
- 拒绝架构空想:每个抽象、接口和层必须根据具体已有的需求证明其存在的价值,而不是基于推测的未来需求(YAGNI)。
- 基于证据的设计:基于具体的性能剖析、测量结果、查询计划(
EXPLAIN ANALYZE)和容量上限来做决策,而非依赖假设。 - 快速失败与显式边界:子系统、领域或网络跳转之间的边界必须拥有显式的、强类型的契约、验证、超时、熔断器和幂等性保证。
2. 高层设计 (HLD) 与架构工作流
当被要求设计一个系统、评估一个架构或重构一个主要子系统时,执行以下 6 步框架:
flowchart TD
Step1["1. 明确需求与范围<br>(功能、非功能性、延迟、可用性、一致性)"]
Step2["2. 容量与规模估算<br>(DAU、QPS、吞吐量、网络带宽、存储、缓存 RAM)"]
Step3["3. 高层架构 (C4 L1/L2)<br>(服务边界、存储选择、入口、缓存)"]
Step4["4. 数据模型与接口契约<br>(实体、模式、主键、索引、REST/gRPC API)"]
Step5["5. 深入分析与瓶颈隔离<br>(复制、分片、并发、缓存病态行为、热点)"]
Step6["6. 弹性与 SRE 策略<br>(SLO、熔断器、带抖动的重试、幂等性、DLQ)"]
Step1 --> Step2 --> Step3 --> Step4 --> Step5 --> Step6
详细 HLD 参考
关于分布式系统定理 (CAP、PACELC)、一致性层次结构、共识算法 (Raft/Paxos)、分片、复制、Saga 模式和事务性发件箱模式,请查阅: 👉 高层系统设计与分布式系统参考
3. 低层设计 (LLD) 与整洁代码标准
在编写、审查或重构代码时,遵循以下标准:
3.1 SOLID 原则
- SRP(单一职责):一个模块只对一个参与者/利益相关者负责。将持久化、HTTP 序列化和业务逻辑分离到不同的关注点中。
- OCP(开闭原则):优先使用多态、策略模式或访问者模式,而不是庞大的
switch/if-else类型分发语句。 - LSP(里氏替换原则):子类型必须满足父类型的所有行为不变量。重写方法以抛出
NotImplementedException违反了 LSP。 - ISP(接口隔离原则):倾向于小型、客户端特定的角色接口,而不是庞大的“上帝接口”。
- DIP(依赖倒置原则):核心业务规则仅依赖于抽象(端口),绝不应直接依赖于外部数据库库、UI 框架或网络驱动程序。
3.2 模块化封装 (Parnas & Connascence)
- 模块秘密:模块必须完全隐藏其主要秘密(内部算法/数据结构)和次要秘密(外部环境/文件格式)。
- 连接性:最小化动态连接性(执行顺序、时序、值约束),并将耦合降至静态名称/类型约定。
详细 LLD 参考
关于 GoF 设计模式现场指南、领域驱动设计 (DDD) 策略构建块(实体、值对象、聚合、领域事件)以及重构技术,请查阅: 👉 低层设计与整洁代码参考
4. API 与数据持久化标准
- RESTful API:
- 严格遵守 HTTP 方法语义(
GET是安全的且幂等的;PUT/DELETE是幂等的;POST用于创建)。 - 使用 RFC 7807 (Problem Details) 来构建结构化的错误响应。
- 对于高容量集合,使用 Keyset/Cursor 分页 而非 Offset/Limit 分页。
- 严格遵守 HTTP 方法语义(
- 数据库索引 (E-R-S 规则):
- 复合索引列顺序:[等值列] $\to$ [范围列] $\to$ [排序列]。
- 使用 覆盖索引(索引仅扫描)和 部分索引 来消除热点查询的磁盘页查找。
- 始终使用
EXPLAIN QUERY PLAN或EXPLAIN ANALYZE验证查询。
- 异步消息与事件:
- 通过将至少一次的代理投递与消费者幂等性(使用唯一消息 ID 在存储中去重)相结合,保证至少一次的有效处理。
- 将不可处理的毒药消息路由到死信队列 (DLQ),以防止分区阻塞。
详细 API 与数据参考
5. 性能、容量与可靠性工程
- 粗略估算:
- $1\text{ 天} \approx 10^5\text{ 秒}$ ($86,400\text{ s}$). $1\text{M 请求/天} \approx 12\text{ RPS}$。
- 峰值 QPS = 平均 QPS $\times$ $3\times$。
- 缓存 RAM = $20% \times (\text{日读取量} \times \text{项大小})$ (帕累托 80/20 法则)。
- Little 定律:$L = \lambda W$(并发数 = 到达率 $\times$ 延迟)。
- 缓存纪律:
- 切勿设置任意未测量的内存 TTL,以免其在正常操作窗口内过期。
- 基于数据版本/指纹或会话时间戳进行失效操作。
- 防范 缓存雪崩(使用互斥锁/分布式锁)、缓存穿透(布隆过滤器)和 缓存击穿(TTL 抖动)。
- 站点可靠性工程 (SRE):
- 强制执行显式的 SLO 和延迟预算($p50$、$p95$、$p99$)。
- 实现熔断器、隔板和带完全抖动的指数退避策略。
详细可靠性与性能参考
6. 架构决策记录 (ADR)
使用标准 ADR 格式记录非平凡的技术选择:
- 背景与驱动因素:问题、操作约束以及延迟/规模目标。
- 考虑过的选项:结构性的替代方案及其权衡。
- 决策与结果:与决策驱动因素相关联的具体理由。
- 后果:明确说明已接受的积极好处和负面成本。