# 27 · 编程语言与后端框架选型 > 一句话点题:**语言和框架不是信仰题,而是约束题。架构师不问「哪个最流行」,而问「这个选择会改变团队速度、运行成本、性能上限、生态可得性和未来迁移成本吗」。如果答案是会,它就是架构决策;如果答案只是写法不同,它就是实现细节。** --- > **🧰 技术栈选型篇第 1 章 · 本章只练一件事** > > 前 26 章一直强调「架构不是框架」。但现实里,你还是要选 Java、Go、Python、TypeScript、Rust,还是某个 Web 框架。技术栈选型篇不是回来教语法,而是把「用什么技术」重新拉回 [02 章](02-架构师的思考框架.md) 的框架:需求、约束、质量属性、取舍。 --- ## 开场:技术选型不是投票 很多团队选语言,像在做投票: ``` 我喜欢 Go → 用 Go 招 Java 容易 → 用 Java AI 生态都在 Python → 用 Python 前后端统一 TS → 用 TypeScript ``` 这些理由不是没用,但它们只是**线索**,不是决策。真正的架构判断要继续往下问: - 这条业务链路的性能瓶颈是什么? - 团队最缺的是交付速度、运行效率、稳定性,还是招聘可得性? - 这个生态里有没有成熟的库、框架、调试工具、监控方案? - 三年后要换人维护,新人能不能读懂、改动、上线? > **判断标准:**如果一个语言/框架选择会显著影响质量属性([06 章](06-质量属性与取舍.md)),它就是架构决策;如果只是代码风格不同,就别把它上升到架构战争。 --- ## 一、先分清:语言、运行时、框架分别影响什么 新手常把三件事混在一起: | 层次 | 它决定什么 | 例子 | 架构上真正要看 | |---|---|---|---| | **语言** | 表达方式、类型系统、生态入口 | Java、Go、Python、TypeScript、Rust | 团队熟悉度、长期维护、错误能否早暴露 | | **运行时** | 并发模型、内存、启动速度、部署形态 | JVM、Node.js、CPython、Go runtime | 延迟、吞吐、资源成本、冷启动 | | **框架** | 约定、组件组合、开发节奏 | Spring Boot、FastAPI、NestJS、Gin | 交付速度、可测试性、插件生态、团队一致性 | 所以,「我们用 Java 还是 Go」不是一个完整问题。更完整的问题是: > 在当前团队、当前业务、当前质量目标下,我们需要一个什么样的**运行与交付模型**? 例如内部 SaaS 后台([案例 02 PatchDesk](../cases/patchdesk-saas/README.md))最初的核心不是极限性能,而是权限、多租户、审计、报表这些业务复杂度。此时成熟框架和团队可维护性,通常比单机 QPS 更重要。 --- ## 二、五把尺子:别从工具名开始 做语言/框架选型,先用五把尺子量: | 尺子 | 要问的问题 | 偏向的选择 | |---|---|---| | **业务复杂度** | 规则多、状态多、权限多吗? | 类型系统强、工程约定强、测试生态成熟 | | **性能与资源** | CPU、内存、尾延迟(P99,最慢 1% 请求)是不是核心? | 运行时开销低、并发模型清晰 | | **生态成熟度** | 支付、鉴权、ORM、消息、监控有没有现成方案? | 生态深、文档多、社区稳定 | | **团队能力** | 团队会什么?招人容易吗?代码评审能不能守住质量? | 团队主语言,或学习成本可控的新语言 | | **交付与演进** | 需要快速迭代,还是长期高可靠? | 框架约定清晰、迁移路径明确 | > **架构智慧:**不要为了「语言更先进」换栈。只有当新技术能明确换来某个质量属性,并且你愿意支付学习、运维、招聘、迁移成本时,它才值得进入候选。 --- ## 三、常见后端语言的架构取舍 下面不是排名,而是帮助你形成判断: | 技术 | 常见优势 | 常见代价 | 适合什么场景 | |---|---|---|---| | **Java / Kotlin + JVM** | 生态成熟、企业库多、性能稳定、可维护性强 | 项目可能偏重,启动慢一些,框架复杂度高 | 中大型业务系统、金融、电商、SaaS 后台 | | **Go** | 部署简单、并发模型直接、资源占用低 | 泛型/工程抽象历史包袱较多,复杂业务表达需要纪律 | 网关、基础设施、微服务、实时链路 | | **Python** | AI/数据生态强、原型快、表达成本低 | 运行性能和并发模型要小心,大型工程需要强约束 | AI 服务、数据平台、自动化、低 QPS 后台 | | **TypeScript / Node.js** | 前后端同语言、I/O 并发友好、生态大 | CPU 密集不合适,依赖生态质量参差 | BFF(Backend for Frontend,面向前端的后端)、中小 SaaS、实时轻服务 | | **Rust** | 性能和内存安全强、适合底层系统 | 学习曲线高、交付速度可能慢 | 存储、代理、引擎、对性能/安全极敏感的组件 | 注意这里的关键词是「组件」。一个系统不一定只能一种语言: ``` 业务主服务: Java / Go / TypeScript AI 推理与数据处理: Python 高性能代理或存储引擎: Rust / Go 前端与 BFF: TypeScript ``` 多语言不是罪,但要小心它带来的**认知税**:构建、部署、监控、调试、招聘、代码审查都会变多。小团队为了「每个模块都用最合适语言」而引入 5 种栈,通常是在提前透支组织能力([15 章](15-组织即架构.md))。 --- ## 四、框架选型:默认选成熟,除非你有明确反证 框架不是越轻越好,也不是越全越好。它本质上是在帮团队做约定: ``` 框架给你: 路由 / 依赖注入 / 配置 / 数据访问 / 鉴权 / 测试 / 可观测性入口 框架也拿走: 自由度 / 学习成本 / 升级成本 / 调试透明度 ``` 如果系统处在 MVP 阶段,你要优先降低交付风险;如果系统会长期多人维护,你要优先降低协作风险。很多时候,**成熟而稍显笨重的框架**,比「很酷但全靠团队自律」的轻框架更稳。 可以用这张表做第一轮筛选: | 问题 | 如果答案是「是」 | 选型倾向 | |---|---|---| | 团队新人多、多人长期维护? | 是 | 约定强、文档好、生态成熟的框架 | | 需要极快试错、业务还不确定? | 是 | 轻量框架 + 清晰模块边界 | | 有大量企业集成、事务、权限? | 是 | 成熟企业框架 | | 是高并发网关/代理? | 是 | 运行时开销低、网络模型成熟的框架 | | 是 AI / 数据密集服务? | 是 | 优先靠近 Python / 数据生态,外层用稳定 API 包起来 | --- ## 五、什么时候该换语言或换框架 不要因为「看起来旧」就换。换技术栈应该由**触发信号**推动: | 触发信号 | 说明 | 可能动作 | |---|---|---| | P99 长期超 SLO(服务等级目标),且瓶颈来自运行时 | 不是写法问题,而是模型不匹配 | 把热点链路拆成更合适的运行时 | | 团队交付越来越慢,框架约定挡路 | 业务复杂度超过原框架承载 | 先模块化,再局部迁移 | | 生态缺失导致大量自研 | 维护成本持续升高 | 换到生态更成熟的栈 | | 招聘和代码审查困难 | 组织能力跟不上技术选择 | 收敛语言,或加强平台约束 | | 安全/合规/性能要求变高 | 旧栈很难补齐能力 | 对关键组件单独升级 | > 对照 [14 章](14-演进与拆分大型系统.md):换栈也要像拆单体一样做。不要「大爆炸重写」,先抽边界、并行运行、影子流量、逐步切换。 --- ## 六、一个可复制的选型结论模板 不要在 ADR 里写「我们选择 Go,因为 Go 很快」。写成这样: ```md ### ADR-027:订单入口服务使用 Go + Gin - 背景:下单入口是 CPU 不重但连接数高的 I/O 链路,P99 目标 200ms,团队已有 Go 运维经验。 - 选择:入口层使用 Go + Gin,业务状态机仍留在 Java 订单服务。 - 放弃:放弃单语言仓库的简单性,增加一条构建链路。 - 换来:入口层部署更轻、连接处理更直接,可以独立扩容和限流。 - 复审条件:如果入口逻辑变成复杂业务编排,或团队 Go 维护能力不足,重新评估是否回收进主业务栈。 ``` 这一段的重点不是 Go,而是**为什么只把入口层切出去**,以及你承认了代价。 --- ## 🎯 随堂检验 --- ## 本章小结 - **语言/框架不是信仰题,是约束题**:先问业务复杂度、性能、生态、团队、演进,再看工具名。 - **分清语言、运行时、框架**:语言影响表达和生态,运行时影响资源与并发,框架影响团队约定和交付节奏。 - **成熟默认优先**:除非你有明确质量属性收益,否则不要为了「先进」换栈。 - **多语言要付认知税**:构建、部署、监控、调试、招聘、审查都会变复杂。 - **换栈也要演进式**:像 [14 章](14-演进与拆分大型系统.md) 一样,抽边界、并行运行、逐步迁移,不要大爆炸重写。 > **承上启下**:语言和框架解决的是「代码如何运行与协作」。但系统真正长期难的是数据。下一章 [28 · 数据库与存储选型](28-数据库与存储选型.md),我们把问题从「服务怎么写」推进到「数据到底放在哪里、怎么查、怎么一致、怎么省钱」。 --- ## 相关链接 - 方法论本体:[02 · 架构师的思考框架](02-架构师的思考框架.md) · [06 · 质量属性与取舍](06-质量属性与取舍.md) · [08 · ADR](08-架构决策记录与演进.md) - 演进配套:[14 · 演进与拆分大型系统](14-演进与拆分大型系统.md) · [15 · 组织即架构](15-组织即架构.md) - 案例对照:[PatchDesk:轻量工单 SaaS](../cases/patchdesk-saas/README.md) · [CodePilot:编码 Agent 平台](../cases/codepilot-agent/README.md)