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

8.9 KiB
Raw Blame History

技术选型框架

后端与全栈技术选型的结构化决策框架。防止分析瘫痪,同时确保严谨评估。

铁律:未经明确的取舍分析,不得做出任何技术选择。

"我喜欢"和"这很热门"都不是工程论证。


阶段一:先定需求,再选技术

非功能性需求(量化!)

维度 问题 糟糕的回答 好的回答
规模 多少并发用户? "很多" "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(架构决策记录)模板

# 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) 不同部署节奏。