mcpField
S
system-design

system-design

github.com/noobygains开发11870 次安装3 天前更新
代码仓库

关于 system-design

system-design 是面向软件项目架构决策的技能,帮助工程师按当前需求选择简单方案,并记录选择依据。它覆盖数据存储、API、认证、缓存、任务队列、部署及文件组织。

主要功能

  1. 01按当前需求分类并约束设计
  2. 02盘点已有环境与服务
  3. 03提供架构和技术选择默认项
  4. 04要求验证可变的供应商信息
  5. 05形成建议并记录决策

适用场景

  1. 01为新项目选择数据库与 API 风格
  2. 02评估是否拆分服务或增加部署单元
  3. 03决定认证、缓存或后台任务方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/noobygains/godmode --skill system-design

安装后在 Claude Code 中输入/system-design确认已加载。

附带文件references/hosting-and-services.md

详细介绍

系统设计

架构中的每个组件都是需要维护的代码、一笔开销,也是一种故障方式。这项技能会选择满足项目当前需求的最简单结构,优先采用用户已经在运行的方案,而不是引入新方案,并记录选择的原因。复杂性必须由当前明确的需求来证明;“我们以后可能会需要”不算理由。

首要原则

NO STRUCTURAL COMPLEXITY WITHOUT A CURRENT, NAMED REQUIREMENT

没有例外。没有变通方案。没有捷径。

适用场景

必须使用:

  • 选择数据库、API 风格、身份验证方案、缓存、队列或任务运行器时。
  • 决定使用单体还是服务,或添加新的可部署组件时。
  • 选择托管、存储、电子邮件、搜索、支付或任何托管服务时。
  • 组织新项目的文件和模块时。
  • 用户询问“我应该用什么”“应该托管在哪里”“我们该如何扩展”,或“要不要迁移到 X”时。

跳过:

  • 用户已经选定技术栈并希望直接实现:尊重其选择并着手构建(指出一次严重风险后继续)。
  • 在现有架构中修复 Bug 或进行小幅修改。

流程

  1. 列出需求并分类。 对每项需求(数据、身份验证、文件、任务、实时功能、电子邮件、支付、搜索、托管),标记为当前必须(缺少它就无法上线)、近期必须(有证据表明实际使用后的头几周内就需要)、锦上添花或推测性需求。只针对前两类进行设计。分类不明确时,一次只问用户一个问题。

  2. 盘点用户已有的资源。 调用 godmode:environment-awareness,盘点机器和项目:已安装的数据库和运行时、容器工具、已登录的云和托管 CLI、正在运行的服务、现有依赖项、引用服务的配置。还要询问用户或其组织已经付费使用哪些账户或平台。已有且适用的方案优先于任何新方案。

  3. 从下方决策表中的默认选项开始。 每个默认选项都是适用于大多数项目的最简单方案。

  4. 只有明确的需求才能作为偏离默认选项的理由。 在偏离方案旁写明需求:“使用队列,因为图像处理需要 40 s,且不能阻塞请求。”如果无法写出这样的理由,就保留默认选项。

  5. 通过 godmode:grounding 在服务商当前页面核实每项可能变化的事实(服务限制、免费层级、定价、区域、运行时支持),并注明来源。托管条款经常变化;绝不要凭记忆引用价格或限制。

  6. 系统架构特殊时,查找参考架构(godmode:reference-first、架构参考资料)。

  7. 按照下方格式给出建议,包含备选方案、切换条件,以及有意未纳入的内容。

  8. 在项目文档中记录决策,写成简短的决策记录(背景、决策、后果、来源),以便对话结束后仍能保留选择理由。

决策表

单体还是服务
情况选择
新项目、单个团队单体(默认),按功能组织
团队之间互相影响、不断扩大的代码库模块边界受到强制约束的模块化单体
有证据表明某个组件现在就需要独立扩展或部署将该组件单独拆出
不同团队分别负责独立领域,且发布周期各不相同按团队边界拆分服务

Martin Fowler 的观察:成功的微服务系统几乎都是从单体起步的;从零开始构建为微服务的系统往往会遇到严重问题。Shopify 为其规模最大的 Rails 代码库之一选择了模块化单体,而不是微服务。

数据库
需求选择
关系型数据、事务、多用户(大多数应用)PostgreSQL(默认)
单服务器或嵌入式场景、写入并发量适中、运维最简单SQLite:一次只能有一个写入者,但写入只需几毫秒;SQLite 作者表示,每天访问量低于 10 万次的网站应该可以顺畅运行
部分记录的结构可变优先使用 PostgreSQL jsonb 列,而非文档数据库
搜索应用数据中的文本优先使用 PostgreSQL 全文搜索,而非搜索引擎
缓存、会话、速率限制计数器、临时数据仅在确有需要时使用 Redis 或兼容存储
搜索相关性、分面搜索,以及超出数据库承载范围的规模专用搜索引擎
对产品占主导地位的时序、图或分析工作负载根据证据选择专用存储

如果用户已经在运行某个数据库,且它符合需求,就使用它。在某种访问模式明确需要单独存储之前,只使用一个数据库。

API 风格
场景选择
CRUD、公共或合作伙伴 API、浏览器客户端使用 JSON 的 REST(默认);设计细节参考 godmode:reference-first
针对嵌套数据适配多种客户端形态、由客户端控制查询GraphQL
有实测吞吐量需求的内部服务间调用、流式传输gRPC
服务器向浏览器推送内容单向流使用服务器发送事件;双向通信使用 WebSockets
向其他系统通知事件已签名的 Webhook(Standard Webhooks)

全栈框架内置的服务器函数用于其自身前端没有问题;只有其他客户端需要时,才添加独立 API。

身份验证
场景选择
单个站点上拥有自有用户的 Web 应用通过框架成熟的身份验证库,使用安全的 HttpOnly Cookie 保存服务器端会话(默认)
社交或企业登录通过维护中的库或提供商使用 OAuth 2.0 / OpenID Connect
由第三方或其他源使用的独立 API使用带刷新机制的短期访问令牌,或用于服务器间通信的 API 密钥
希望快速获得完善的托管 UI、组织功能和 SSO使用托管身份提供商,前提是用户接受其成本和锁定风险

切勿从头编写密码哈希、会话处理或令牌验证。无状态令牌在到期前无法撤销,除非增加额外机制;会话则可以撤销。安全审查请参阅 godmode:security-protocol(以及 OWASP Authentication Cheat Sheet)。

缓存

只有以下三个条件全部满足时才添加缓存:已实测存在性能问题;无法简单修复查询或代码;数据的读取远多于写入,并且可以接受轻微过时。

层级适用场景
HTTP 缓存和 CDN静态资源和公共页面(优先使用,成本最低)
进程内存单个实例、小规模数据
共享缓存(Redis 或兼容存储)多个实例需要共享相同的缓存数据
物化视图数据库中的高开销聚合

默认情况下不使用缓存。每种缓存上线前都必须记录失效规则。

队列和后台任务
需求选择
工作可在请求中完成直接调用(默认)
偶发的耗时工作、需要重试、已使用 PostgreSQL基于 Postgres 的任务队列(例如 Node.js 的 pg-boss)
任务较多、已使用 Redis基于 Redis 的队列(Node.js 的 BullMQ、Python 的 Celery)
失败后必须能够恢复的多步骤工作流、无服务器托管持久化工作流服务(例如 Inngest,可从失败步骤开始重试)
需要重放、拥有多个消费者且数据量大的事件流基于日志的代理,例如 Kafka,并须有数据量证据
定时任务优先使用主机的 cron 或调度器
托管与服务

先根据用户已经在使用的服务选择,再根据工作负载的特点选择。比较内容及各供应商当前限制和定价页面的链接见 hosting-and-services.md。规则如下:

  • 如果已有合适的部署平台:继续使用。
  • 如果框架有一方托管平台,且用户对其满意:默认选择该平台。
  • 如果流量稳定、使用容器且需要完全控制:选择 VPS 或容器平台。
  • 如果流量波动大或较低,且以静态内容为主:选择静态托管加无服务器函数。
  • 如果合适,能同时提供数据库、身份验证和存储的单一供应商,胜过把三家供应商拼在一起。

文件组织

按功能组织,而非按技术层组织,这样一次更改只涉及一个目录:

src/
  billing/
    billing.routes.ts
    billing.service.ts
    billing.repository.ts
    billing.test.ts
  accounts/
    ...
  shared/
    db.ts
    auth.middleware.ts
    logger.ts

在现有项目中,遵循其布局(godmode:codebase-conventions),即使它是按层组织的。对于新项目,使用 godmode:project-bootstrap 进行搭建。

展示建议

Requirements
- <need>: required now / required soon / nice to have (deferred) / speculative (dropped)

Already available
- <databases, runtimes, CLIs, accounts found>

Recommended
| Layer | Choice | Why (requirement, and what the user already has) | Source |
Expected running cost: <from the vendor's current pricing page, dated>, or "free tier covers current scale" with the limit cited.

Alternative and when to switch
| Layer | Alternative | Switch when <measurable trigger> |

Deliberately not used
- <service or pattern>: <why it is not needed now>

保持适度:周末项目写五行即可。

思维陷阱

合理化说辞事实
“以后我们可能需要微服务。”以后拆分是可行的;合并过早拆开的服务则很痛苦。先从单体架构开始。
“NoSQL 更灵活。”PostgreSQL 可以存储 JSON。没有架构的灵活性通常会变成混乱。
“现在大家都用 X。”流行不代表有此需求。这个项目需要什么?用户已经在运行什么?
“JWT 更安全。”JWT 更难撤销。对于单个网站,会话更简单。
“我们需要缓存来提升速度。”先测量。大多数性能问题出在查询或 N+1,而不是缺少缓存。
“队列能让它可扩展。”队列会增加一个活动部件。只有当工作无法在请求中完成时才使用。
“无服务器总是更便宜。”这取决于流量特征。请查看当前针对这种工作负载的定价。
“我记得免费套餐的情况。”免费套餐和限制会变化。今天就阅读供应商页面并注明来源。

防护措施

绝不:

  • 为尚未证实的扩展需求添加基础设施。
  • 未先检查用户已有资源,就推荐新服务。
  • 不引用当前来源就给出价格、限制或免费套餐信息。
  • 在用户已有的某项服务足以满足需求时,叠加多项托管服务。
  • 推翻用户已选择的技术栈;说明一次风险,然后继续构建。

始终:

  • 在选择之前,对每项需求进行分类。
  • 每当偏离默认方案时,在旁边写明对应需求。
  • 提供替代方案,并给出可衡量的切换触发条件。
  • 说明省略了什么以及原因。
  • 记录决策及其来源。

关联

  • godmode:environment-awareness:提供用户当前运行内容的清单;选择托管和服务时始终先使用它。
  • godmode:rationale:在本技能决定如何实现之前,先审视该功能是否真的需要构建。
  • godmode:reference-first:提供参考架构以及 API、架构和 CI 参考资料。
  • godmode:grounding:核实供应商的限制、定价和功能。
  • godmode:security-protocol:审查身份验证、数据流和机密信息处理。
  • godmode:performance-tuning:在进行任何缓存或扩展更改之前先测量。
  • godmode:project-bootstrap:在新仓库中搭建所选结构。

评论

支持 Markdown