大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
软件架构是什么
这一课你将能做到
- 用一句话向非技术人员解释「软件架构」,并说出架构师与高级开发的本质区别
- 画出本站从单体 Spring Boot 演进到微服务的架构分层图,标出每一层的职责
- 写出一份符合规范的 ADR(架构决策记录),能直接放进项目仓库
为什么要学
写代码解决的是「这个功能怎么实现」,架构解决的是「这个功能放在哪、和谁通信、挂了怎么办」。功能写错了改一个类就行,架构错了要推翻重写整个系统。
人话:架构就像城市规划。开发是盖楼,架构师决定哪里是住宅区、哪里是商业区、路怎么修、水电怎么走。楼盖歪了可以拆,城市规划错了全城堵车十年。
面试场景:面试官问你「你们系统架构是怎样的」,如果你只会说「Spring Boot + MySQL」,那是技术栈罗列,不是架构。能讲清楚「为什么这样分层、瓶颈在哪、下一步怎么演进」,才是架构思维。
先建立图像
本站(CodeRoadMap)架构演进的三个阶段:
【阶段一:单体】(起步期,1 个开发者)
┌─────────────────────────────────┐
│ Spring Boot 单体应用 │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │用户模块│ │课程模块│ │支付模块│ │
│ └──┬───┘ └──┬───┘ └──┬───┘ │
│ └────────┴────────┘ │
│ 共享 Service/DAO │
└──────────────┬──────────────────┘
│ JDBC
┌──────┴──────┐
│ MySQL │
└─────────────┘
【阶段二:单体 + 缓存】(日活 1 万)
浏览器 → Nginx → Spring Boot ──→ Redis(热点课程缓存)
│
MySQL(主)→ MySQL(从,读写分离)
【阶段三:微服务】(日活 10 万+,团队 20 人)
┌──→ 用户服务 ──→ MySQL(用户库)
Nginx → API Gateway ──→ 课程服务 ──→ MySQL(课程库)+ Redis
│ │
└──→ 订单服务 ──┴──→ RocketMQ(下单事件)──→ 推荐服务
跟着做
步骤 1:识别架构的四个层次
任何系统都可以拆成四层来看,用本站举例:
| 层次 | 问题 | 本站的答案 |
|---|---|---|
| 应用架构 | 代码怎么组织? | 单体按包划分:controller/service/dao/domain |
| 系统架构 | 进程怎么部署? | 阶段一:1 个 JVM 进程 + 1 个 MySQL |
| 数据架构 | 数据存哪、怎么流? | MySQL 主库,课程表按 track_id 分索引 |
| 基础设施 | 跑在哪? | 阶段一:1 台云服务器;阶段三:K8s 集群 |
步骤 2:做一次架构推演
假设需求:「给本站加课程搜索功能」。架构师的思考路径:
- 数据量级?课程表 5000 行 → MySQL LIKE 够用;50 万行 → 必须上 Elasticsearch
- QPS 多少?日活 1 万 → 峰值约 50 QPS,MySQL 扛得住
- 一致性要求?课程更新后 5 分钟内可被搜到即可 → 允许近实时
- 结论:当前用 MySQL 全文索引,预留 ES 演进路径,写入侧用 Canal 监听 binlog 同步
步骤 3:写一份 ADR
架构决策记录(Architecture Decision Record)是架构师的核心产出物:
# ADR-003: 课程搜索使用 MySQL 全文索引而非 Elasticsearch
## 状态
已接受(2024-06-01)
## 背景
课程总量 5000,日搜索请求约 2 万次,团队无 ES 运维经验。
## 决策
使用 MySQL 8 的 ngram 全文索引,搜索接口走从库。
当课程数超过 5 万或搜索延迟 P99 超过 500ms 时,重新评估迁移 ES。
## 后果
+ 零新增基础设施,运维成本不变
+ 数据与业务库强一致,无同步延迟
- 中文分词精度低于 ES 的 ik 分词器
- 复杂排序(相关性打分)能力受限
讲清楚要点
- 架构 = 结构 + 决策 + 权衡:结构是「有什么组件、怎么连」,决策是「为什么这么选」,权衡是「放弃了什么」。三者缺一都不算架构。
- 没有最好的架构,只有最合适的架构:本站阶段三对日活 1 万的系统是灾难——分布式事务、服务治理的复杂度会拖死小团队。
- 架构师 vs Tech Lead:Tech Lead 对「这个 Sprint 交付什么」负责,架构师对「这个系统三年后还能不能演进」负责。小公司常一人兼任,但职责要分清。
- Solution Architecture vs Enterprise Architecture:前者管单个系统(本站的课程服务),后者管整个企业的系统版图(CRM、ERP、数据平台如何协同)。本 track 聚焦前者。
- 架构是演进的,不是设计的:没人一开始就设计出淘宝架构。正确姿势是「满足当前需求 + 留好演进接口 + 定期偿还技术债」。
你可能会懵的地方
-
架构设计不就是画框图吗? 框图只是结果的呈现。架构的核心工作在框图之前:识别约束(预算、团队、时间)、列出备选方案、评估权衡。一张没有决策依据的框图没有价值。
-
小项目需要架构吗? 需要,但程度不同。5000 行代码的项目,架构可能就是「分层 + 一份 README 说明」;50 万行的系统需要正式的架构文档。架构投入的多少本身就是架构决策。
-
架构师还需要写代码吗? 需要。不写代码的架构师会逐渐失去对实现成本的判断力,做出「PPT 架构」。业界共识是架构师至少保留 30% 的编码时间。
-
学了架构能马上用吗? 能。哪怕你只是普通开发,用架构思维写代码:模块边界清晰、依赖方向正确、变更影响可控——这就是架构能力在日常的体现。
-
微服务是不是比单体高级? 不是。微服务是用「分布式复杂度」换「团队并行度和独立部署能力」。团队小于 10 人、日活低于 10 万,单体 + 模块化通常是更优解。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 上来就拆微服务 | 分布式事务、运维复杂度压垮小团队 | 单体模块化先行,边界清晰后再拆 |
| 用消息队列解耦一切 | 链路不可追踪,排查问题要翻 5 个系统 | 只对「异步、削峰、最终一致」场景用 MQ |
| 技术选型追新(Service Mesh 全套) | 学习成本高,社区不成熟踩坑无人救 | 选团队能 Hold 住的最简单方案 |
| 架构文档写完不更新 | 三个月后文档与现实脱节,误导新人 | ADR 随代码提交,架构图每个季度复审 |
| 为「以后可能的需求」过度设计 | 80% 的预留设计永远不会被用到 | YAGNI:当前需求 + 留扩展点即可 |
卡点急救
- 拿到需求不知道从何下手:先问四个问题——数据量多大?并发多少?一致性要求多强?预算和 deadline?这四个答案基本锁定架构大方向。
- 评审时被人挑战方案,说不出依据:回到 ADR 的格式,把「背景-决策-后果」写清楚,用数据说话(QPS、延迟、成本),而不是「我觉得」。
- 老系统没人敢动,新需求越来越多:这是典型的技术债信号。做法:新功能用新架构(绞杀者模式),老功能按调用频率排序逐步迁移,不要大爆炸重写。
面试常问
-
单体和微服务怎么选? 答题框架:团队规模(<10 人倾向单体)、业务复杂度(领域边界是否清晰)、部署频率要求(是否需独立发布)、运维能力(有无 K8s 和监控体系)。举例:本站日活 1 万时单体 + 读写分离是合理选择;日活 10 万、团队 20 人后按域拆出课程、订单、推荐服务。记住金句:「微服务解决的是组织问题,其次才是技术问题」。
-
什么是架构决策记录 ADR? 一份轻量文档,记录某个架构决策的背景、选项、决策和后果,随代码版本管理。价值:新人能快速理解「为什么是这样」,避免后人推翻决策时不知道当初的约束。结构:标题、状态、背景、决策、后果五部分。
-
如何评估一个架构好不好? 看四个非功能属性:可维护性(改一个需求动几个模块)、可扩展性(加 10 倍流量加什么)、可用性(挂一个组件影响多大)、成本(机器 + 人力)。好的架构是在当前约束下这四个属性的最优平衡点。
自测三问
- 用一句话说明架构师和高级开发的职责差异?
- 本站在日活 1 万时为什么不该拆微服务?至少说出两个理由。
- 一份合格的 ADR 必须包含哪五个部分?
小结一句话
架构是在约束条件下对系统结构和演进方向做权衡的艺术,核心产出是可追溯的决策,而不是漂亮的框图。
延伸
- 《架构整洁之道》(Clean Architecture, Robert C. Martin)——依赖规则必读
- 《软件架构:架构模式、特征及实践指南》(Fundamentals of Software Architecture)
- roadmap.sh/software-architect
- 下一课:架构师软技能——技术之外,沟通、估算与决策推进才决定方案能否落地。