architect

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Architect — System Design

架构设计 — 系统架构

Structure the system before building it. Good architecture makes everything easier. Bad architecture makes everything a rewrite.
在构建系统前先进行架构设计。优秀的架构会让所有事情变得简单,糟糕的架构则会导致所有内容都需要重写。

Step 0: Understand Constraints

步骤0:明确约束条件

Before designing, answer:
  1. Scale — 100 users or 100,000? Determines everything.
  2. Team size — Solo founder or 10 engineers? Simpler systems for smaller teams.
  3. Budget — Bootstrapped or funded? Managed services vs self-hosted.
  4. Timeline — MVP in 2 weeks or v1 in 3 months?
  5. Compliance — HIPAA, SOC 2, GDPR? Constrains architecture choices.
在开始设计前,先回答以下问题:
  1. 规模 — 是100个用户还是100,000个用户?这决定了所有设计选择。
  2. 团队规模 — 是独立创始人还是10人工程师团队?小团队适合更简单的系统。
  3. 预算 — 是自筹资金还是有外部投资?选择托管服务还是自部署?
  4. 时间线 — 是2周内完成MVP还是3个月内推出v1版本?
  5. 合规要求 — 是否需要符合HIPAA、SOC 2、GDPR等标准?这会限制架构选项。

Architecture Patterns

架构模式

PatternWhen to UseWhen to Avoid
Monolith<10 engineers, single product, moving fastMultiple teams needing independent deploys
Modular monolithGrowing team, want boundaries without infra costNeed independent scaling per service
Microservices20+ engineers, distinct domains, independent scalingSmall team, early stage, unclear boundaries
ServerlessEvent-driven, spiky traffic, want zero opsLong-running processes, cost-sensitive at scale
Event-drivenAsync workflows, decoupled systems, audit trailsSimple CRUD, real-time requirements
Default: Monolith until it hurts. Premature microservices is the #1 architecture mistake.
模式适用场景避免场景
单体架构团队人数少于10人、单一产品、快速迭代多团队需要独立部署的场景
模块化单体架构团队规模增长,希望在不增加基础设施成本的前提下划分边界需要按服务独立扩容的场景
微服务架构团队人数20+、业务领域清晰、需要独立扩容小团队、早期阶段、业务边界不明确的场景
无服务器架构事件驱动、流量波动大、希望零运维长运行时进程、规模化后对成本敏感的场景
事件驱动架构异步工作流、解耦系统、审计追踪简单CRUD操作、实时性要求高的场景
默认选择:在单体架构遇到明显瓶颈前,不要轻易切换。过早采用微服务是排名第一的架构设计错误。

Database Selection

数据库选型

NeedDatabaseWhy
General purpose, relationalPostgreSQLACID, JSON support, extensions, ecosystem
Key-value, cachingRedis / ValkeySub-ms reads, TTL, pub/sub
Document store, flexible schemaMongoDBRapid prototyping, nested documents
Full-text searchPostgreSQL FTS or MeilisearchPostgres built-in is good enough until it isn't
Time-seriesTimescaleDB (Postgres extension)Keep one database engine
Graph relationshipsPostgreSQL with recursive CTEsDon't add Neo4j unless graph is the core product
Vector / embeddingspgvector (Postgres extension)Same — keep one database
Rules:
  • Start with Postgres. Add specialized databases only when Postgres can't do the job.
  • Managed always (Supabase, Neon, RDS). Don't manage your own database.
  • One database engine until you have a DBA. Two databases = two problems.
需求数据库原因
通用型、关系型PostgreSQL支持ACID、JSON、扩展插件,生态完善
键值对、缓存Redis / Valkey亚毫秒级读取、支持TTL、发布/订阅
文档型、灵活SchemaMongoDB快速原型开发、支持嵌套文档
全文搜索PostgreSQL FTSMeilisearch在性能不足前,Postgres内置的全文搜索足够使用
时序数据TimescaleDB(Postgres扩展)保持单一数据库引擎
图关系PostgreSQL(配合递归CTE)除非图是核心产品,否则不要引入Neo4j
向量/嵌入pgvector(Postgres扩展)同上 — 保持单一数据库引擎
规则:
  • 从PostgreSQL开始。只有当PostgreSQL无法满足需求时,再引入专用数据库。
  • 始终使用托管服务(如Supabase、Neon、RDS),不要自行管理数据库。
  • 在拥有专职DBA前,只使用一种数据库引擎。两种数据库意味着两倍的问题。

Project Structure

项目结构

TypeScript / Next.js

TypeScript / Next.js

src/
├── app/                    # Next.js app router — pages and layouts
│   ├── (auth)/             # Route groups for auth pages
│   ├── (dashboard)/        # Route groups for app pages
│   └── api/                # API routes
├── lib/                    # Shared utilities, config, constants
│   ├── db/                 # Database client, schema, migrations
│   ├── auth/               # Auth config and helpers
│   └── utils/              # Pure utility functions
├── services/               # Business logic — one file per domain
│   ├── user.service.ts
│   └── billing.service.ts
├── components/             # React components
│   ├── ui/                 # Primitives (button, input, card)
│   └── features/           # Feature-specific composites
└── types/                  # Shared TypeScript types
src/
├── app/                    # Next.js 应用路由 — 页面与布局
│   ├── (auth)/             # 路由分组:认证相关页面
│   ├── (dashboard)/        # 路由分组:应用主页面
│   └── api/                # API 路由
├── lib/                    # 共享工具、配置、常量
│   ├── db/                 # 数据库客户端、Schema、迁移脚本
│   ├── auth/               # 认证配置与辅助工具
│   └── utils/              # 纯工具函数
├── services/               # 业务逻辑 — 每个领域一个文件
│   ├── user.service.ts
│   └── billing.service.ts
├── components/             # React 组件
│   ├── ui/                 # 基础组件(按钮、输入框、卡片)
│   └── features/           # 特定功能的复合组件
└── types/                  # 共享 TypeScript 类型

Python / FastAPI

Python / FastAPI

src/
├── api/                    # Route handlers
│   ├── v1/                 # Versioned endpoints
│   └── deps.py             # Shared dependencies (auth, db session)
├── core/                   # Config, security, constants
├── models/                 # SQLAlchemy models
├── schemas/                # Pydantic request/response schemas
├── services/               # Business logic — one file per domain
├── repositories/           # Data access layer
└── tests/
    ├── unit/
    └── integration/
Rules:
  • Feature code stays together. Don't scatter a feature across 8 directories.
  • Services contain business logic. Routes are thin — validate, call service, respond.
  • One service per domain.
    user.service.ts
    not
    getUserById.ts
    ,
    updateUser.ts
    , etc.
src/
├── api/                    # 路由处理器
│   ├── v1/                 # 版本化接口
│   └── deps.py             # 共享依赖(认证、数据库会话)
├── core/                   # 核心配置、安全、常量
├── models/                 # SQLAlchemy 模型
├── schemas/                # Pydantic 请求/响应 Schema
├── services/               # 业务逻辑 — 每个领域一个文件
├── repositories/           # 数据访问层
└── tests/
    ├── unit/
    └── integration/
规则:
  • 功能代码要集中存放,不要将一个功能分散到8个目录中。
  • 服务层包含业务逻辑,路由层要简洁——仅做验证、调用服务、返回响应。
  • 每个领域对应一个服务文件,比如使用
    user.service.ts
    ,而不是拆分成
    getUserById.ts
    updateUser.ts
    等多个文件。

API Design

API设计

DecisionDefault
ProtocolREST for CRUD, tRPC for type-safe full-stack, GraphQL only if multiple clients need different shapes
VersioningURL path:
/api/v1/
— simple, explicit
AuthBearer token in Authorization header
PaginationCursor-based for feeds, offset for admin tables
Errors
{ error: { code: "NOT_FOUND", message: "User not found" } }
Rate limiting100 req/min default, lower for auth endpoints
决策项默认选择
协议CRUD场景用REST,全栈类型安全场景用tRPC,仅当多个客户端需要不同数据结构时才用GraphQL
版本控制URL路径:
/api/v1/
— 简单、明确
认证在Authorization头中使用Bearer令牌
分页信息流用基于游标分页,后台表格用基于偏移量分页
错误处理格式为
{ error: { code: "NOT_FOUND", message: "用户不存在" } }
限流默认100次请求/分钟,认证接口限流阈值更低

Caching Strategy

缓存策略

LayerToolTTLUse When
BrowserCache-Control headersVariesStatic assets, API responses
CDNCloudflare / Vercel Edge1-60 minPublic pages, images
ApplicationRedis / in-memory5-60 minExpensive queries, session data
DatabaseMaterialized viewsRefresh on writeAggregations, dashboards
Rules:
  • Cache reads, not writes. Invalidate on mutation.
  • Start with no cache. Add caching when you measure a bottleneck.
  • Every cache needs an invalidation strategy. "TTL and hope" works until it doesn't.
层级工具过期时间(TTL)适用场景
浏览器Cache-Control 响应头按需设置静态资源、API响应
内容分发网络(CDN)Cloudflare / Vercel Edge1-60分钟公开页面、图片
应用层Redis / 内存缓存5-60分钟高开销查询、会话数据
数据库层物化视图写入时刷新聚合查询、仪表盘
规则:
  • 缓存读操作,不要缓存写操作。数据变更时要失效缓存。
  • 初始阶段不使用缓存。只有当检测到性能瓶颈时再添加缓存。
  • 每个缓存都需要失效策略。“依赖TTL过期”的方式在初期有效,但无法解决所有问题。

Scaling Checklist

规模化 Checklist

Only optimize when you hit the problem:
UsersLikely BottleneckFix
0-1KNothingDon't optimize
1K-10KDatabase queriesAdd indexes, optimize N+1s
10K-100KDatabase connectionsConnection pooling (PgBouncer)
100K-1MRead throughputAdd Redis cache layer
1M+Write throughputRead replicas, sharding, queue writes
The best architecture is the simplest one that handles your current scale + 10×.
只有当遇到问题时再进行优化:
用户规模可能的瓶颈解决方案
0-1K无需优化
1K-10K数据库查询添加索引、优化N+1查询
10K-100K数据库连接数连接池(PgBouncer)
100K-1M读吞吐量添加Redis缓存层
1M+写吞吐量读副本、分片、写入队列
最佳架构是能够处理当前规模10倍增长的最简单架构。