# 技术选型框架 后端与全栈技术选型的结构化决策框架。防止分析瘫痪,同时确保严谨评估。 **铁律:未经明确的取舍分析,不得做出任何技术选择。** "我喜欢"和"这很热门"都不是工程论证。 --- ## 阶段一:先定需求,再选技术 ### 非功能性需求(量化!) | 维度 | 问题 | 糟糕的回答 | 好的回答 | |-----------|----------|-----------|-------------| | 规模 | 多少并发用户? | "很多" | "1K 并发,500 RPS 峰值" | | 延迟 | 可接受的 p99 响应时间? | "快" | "API < 200ms,报告 < 2s" | | 可用性 | 需要的正常运行时间? | "永远在线" | "99.9%(年停机 8.7 小时)" | | 数据量 | 预计存储增长? | "很多" | "100GB/年,1000 万行" | | 一致性 | 强一致还是最终一致? | "一致" | "支付强一致,信息流最终一致" | | 合规性 | 监管要求? | "有一些" | "GDPR 数据驻留欧盟,SOC 2 Type II" | ### 团队约束 - 团队规模与资深程度 - 团队已熟练掌握的技术 - 能否为此技术栈招到人?(查看招聘市场) - 时间压力(几天还是几个月上线) - 许可、基础设施、培训的预算 --- ## 阶段二:评估矩阵 对每个选项按加权标准打分 1-5 分: | 评估标准 | 权重 | 选项 A | 选项 B | 选项 C | |-----------|--------|----------|----------|----------| | 满足功能性需求 | 5× | _ | _ | _ | | 满足非功能性需求 | 5× | _ | _ | _ | | 团队经验 / 学习曲线 | 4× | _ | _ | _ | | 生态成熟度(库、工具) | 3× | _ | _ | _ | | 社区与长期 viability | 3× | _ | _ | _ | | 运维复杂度 | 3× | _ | _ | _ | | 招聘人才池 availability | 2× | _ | _ | _ | | 成本(许可 + 基础设施 + 培训) | 2× | _ | _ | _ | | **加权总分** | | _ | _ | _ | **规则:** - 任何选项在 **5× 标准上得 1 分** → 自动淘汰 - 选项间差距在 **10% 以内** → 选团队最熟悉的 - 选项间差距在 **15% 以内** → 进行**有时间限制的概念验证**(最长 2-5 天) --- ## 阶段三:决策树 ### 后端语言 / 框架 ``` 什么类型的项目? │ ├─ REST/GraphQL API,快速开发 │ ├─ 团队熟悉 TypeScript → Node.js │ │ ├─ 功能完备,企业级模式 → NestJS │ │ ├─ 轻量灵活 → Fastify / Hono / Express │ │ └─ 全栈 + React → Next.js API routes │ ├─ 团队熟悉 Python │ │ ├─ 高性能异步 API → FastAPI │ │ ├─ 全栈,后台管理繁重 → Django │ │ └─ 轻量级 → Flask / Litestar │ └─ 团队熟悉 Java/Kotlin │ ├─ 企业级,大型团队 → Spring Boot │ └─ 轻量级,启动快 → Quarkus / Ktor │ ├─ 高并发,系统级 │ ├─ 微服务,网络编程 → Go │ ├─ 极致性能,安全性 → Rust (Axum / Actix) │ └─ 容错性 → Elixir (Phoenix) │ ├─ 实时(WebSocket、流式) │ ├─ Node.js 生态 → Socket.io / ws │ ├─ 可扩展的发布/订阅 → Elixir Phoenix │ └─ 低延迟 → Go / Rust │ └─ 机器学习 / 数据密集 └─ Python (FastAPI + ML libs) ``` ### 数据库 ``` 什么数据模型? │ ├─ 结构化,关系型,ACID │ ├─ 通用 → PostgreSQL ← 默认选择 │ ├─ 读密集,MySQL 生态 → MySQL / MariaDB │ └─ 嵌入式 / 无服务器边缘 → SQLite / Turso / D1 │ ├─ 半结构化,灵活 schema │ ├─ 文档型 → MongoDB │ ├─ 无服务器文档 → DynamoDB / Firestore │ └─ 搜索密集 → Elasticsearch / OpenSearch │ ├─ 键值 / 缓存 │ ├─ 内存 + 数据结构 → Redis / Valkey │ └─ 星球级 KV → DynamoDB / Cassandra │ ├─ 时间序列 → TimescaleDB / ClickHouse / InfluxDB ├─ 图 → Neo4j / Apache AGE (Postgres 扩展) └─ 向量(AI 嵌入) → pgvector / Pinecone / Qdrant ``` **默认:** 从 PostgreSQL 开始。它能处理 80% 的使用场景。 ### 缓存策略 | 模式 | 技术 | 何时使用 | |---------|-----------|------| | 应用缓存 | Redis / Valkey | 会话、频繁读取、限流 | | HTTP 缓存 | CDN (Cloudflare/Vercel) | 静态资源、公开 API 响应 | | 查询缓存 | 物化视图 | 复杂聚合、仪表盘 | | 进程内缓存 | LRU(内存) | 配置、小型查找表 | | 边缘缓存 | Cloudflare KV / Vercel KV | 全球低延迟读取 | ### 消息队列 / 事件流 | 模式 | 技术 | 何时使用 | |---------|-----------|------| | 任务队列(后台作业) | BullMQ / Celery / SQS | 邮件、导出、支付 | | 事件流(回放、审计) | Kafka / Redpanda | 事件溯源、实时管道 | | 轻量发布/订阅 | Redis Streams / NATS | 简单通知、广播 | | 请求-回复(异步同步化) | NATS / RabbitMQ RPC | 内部服务调用 | ### 托管 / 部署 | 模式 | 技术 | 何时使用 | |-------|-----------|------| | 无服务器(自动扩缩) | Vercel / Cloudflare Workers / Lambda | 流量波动、按量付费 | | 容器(可预测) | Cloud Run / Render / Railway / Fly.io | 流量稳定、运维简单 | | Kubernetes(大规模) | EKS / GKE / AKS | 10+ 服务、团队有 K8s 经验 | | VPS(完全控制) | DigitalOcean / Hetzner / EC2 | 工作负载可预测、对成本敏感 | --- ## 阶段四:决策文档 ### ADR(架构决策记录)模板 ```markdown # ADR-{NNN}: {标题} ## 状态:提议 | 已接受 | 已废弃 | 被 ADR-{NNN} 取代 ## 背景 我们在解决什么问题?有哪些因素在起作用? ## 决策 我们选择了什么以及为什么? ## 评估 | 标准 | 权重 | 选中方案 | 备选方案 | |-----------|--------|--------|-----------| ## 影响 - 正面:... - 负面:... - 风险:... ## 已拒绝的备选方案 - 选项 B:因...被拒绝 - 选项 C:因...被拒绝 ``` --- ## 常见技术栈模板 ### A:初创 / MVP(速度优先) | 层 | 选择 | 理由 | |-------|--------|-----| | 语言 | TypeScript | 前后端统一语言 | | 框架 | Next.js(全栈)或 NestJS(API) | 快速迭代 | | 数据库 | PostgreSQL (Supabase / Neon) | 托管服务,慷慨的免费额度 | | 认证 | Better Auth / Clerk | 无需维护认证代码 | | 缓存 | Redis (Upstash) | 对无服务器友好 | | 托管 | Vercel / Railway | 零配置部署 | ### B:SaaS / 商业应用(平衡) | 层 | 选择 | 理由 | |-------|--------|-----| | 语言 | TypeScript 或 Python | 团队偏好 | | 框架 | NestJS 或 FastAPI | 结构化、可测试 | | 数据库 | PostgreSQL | 可靠、功能丰富 | | 队列 | BullMQ (Redis) | 简单的后台任务 | | 认证 | OAuth 2.0 + JWT | 标准、灵活 | | 托管 | AWS ECS / Cloud Run | 可扩缩容器 | | 监控 | Datadog / Grafana + Prometheus | 完整可观测性 | ### C:高性能(规模优先) | 层 | 选择 | 理由 | |-------|--------|-----| | 语言 | Go 或 Rust | 最大吞吐量、低延迟 | | 数据库 | PostgreSQL + Redis + ClickHouse | OLTP + 缓存 + 分析 | | 队列 | Kafka / Redpanda | 高吞吐量流处理 | | 托管 | Kubernetes (EKS/GKE) | 细粒度扩缩 | | 监控 | Prometheus + Grafana + Jaeger | 指标 + 追踪 | ### D:AI / 机器学习应用 | 层 | 选择 | 理由 | |-------|--------|-----| | 语言 | Python(API)+ TypeScript(前端) | 机器学习库 + 现代 UI | | 框架 | FastAPI + Next.js | 异步 + SSR | | 数据库 | PostgreSQL + pgvector | 关系型 + 嵌入 | | 队列 | Celery + Redis | 机器学习任务处理 | | 托管 | Modal / AWS GPU / Replicate | GPU 访问 | --- ## 反模式 | # | ❌ 不要做 | ✅ 应该做 | |---|---------|--------------| | 1 | "X 在 HN 上火了" | 对照**你自己的需求**来评估 | | 2 | 简历驱动开发 | 选团队能维护的 | | 3 | "必须支持 100 万用户"(第一天) | 按当前需求的 10 倍构建,而非 1000 倍 | | 4 | 评估好几周 | 限制在 3-5 天,然后做决定 | | 5 | 不做决策文档 | 为每个重大选择写 ADR | | 6 | 忽略运维成本 | 将部署、监控、调试成本纳入考量 | | 7 | "以后重写" | 假设不会重写。慎重选择。 | | 8 | 默认微服务 | 从单体开始,需要时再拆分 | | 9 | 每个服务一个不同数据库(第一天) | 用一个数据库,有充分理由再拆分 | | 10 | "谷歌就是这么做的" | 你不是谷歌。按**你自己的场景**来扩缩。 | --- ## 常见问题 ### 问题 1:"团队无法就框架达成一致" **解决方法:** 限制在 3 天内。填写评估矩阵。如果分数相差在 10% 以内,选多数人熟悉的。写入 ADR。继续推进。 ### 问题 2:"我们选了 X,但它不合适" **解决方法:** 检查沉没成本谬误。如果投入不到 2 周,立即切换。如果已超过 2 周,记录痛点并规划分阶段迁移。 ### 问题 3:"我们需要微服务吗?" **解决方法:** 几乎肯定不需要。从一个结构良好的单体开始。仅在以下情况才提取为服务:(a) 不同扩缩需求,(b) 不同团队所有权,(c) 不同部署节奏。