Files
skillhub-052-fullstack-dev/references/technology-selection.md
T
2026-07-13 21:35:57 +08:00

255 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 技术选型框架
后端与全栈技术选型的结构化决策框架。防止分析瘫痪,同时确保严谨评估。
**铁律:未经明确的取舍分析,不得做出任何技术选择。**
"我喜欢"和"这很热门"都不是工程论证。
---
## 阶段一:先定需求,再选技术
### 非功能性需求(量化!)
| 维度 | 问题 | 糟糕的回答 | 好的回答 |
|-----------|----------|-----------|-------------|
| 规模 | 多少并发用户? | "很多" | "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(全栈)或 NestJSAPI | 快速迭代 |
| 数据库 | PostgreSQL (Supabase / Neon) | 托管服务,慷慨的免费额度 |
| 认证 | Better Auth / Clerk | 无需维护认证代码 |
| 缓存 | Redis (Upstash) | 对无服务器友好 |
| 托管 | Vercel / Railway | 零配置部署 |
### BSaaS / 商业应用(平衡)
| 层 | 选择 | 理由 |
|-------|--------|-----|
| 语言 | 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 | 指标 + 追踪 |
### DAI / 机器学习应用
| 层 | 选择 | 理由 |
|-------|--------|-----|
| 语言 | PythonAPI+ 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) 不同部署节奏。