前言

《凤凰架构》是周志明老师撰写的一本关于软件架构演进的著作,不仅内容质量极高,而且阅读起来就像小说一样畅快。本书从单体架构到微服务、从 Spring Cloud 到 Kubernetes,系统地讲述了现代软件架构的演进历程和设计哲学。本文记录了书中的核心思想以及我的思考。

结论先行

软件架构的本质是管理复杂性。 没有完美的架构,只有适合当前阶段的架构。架构应该随着业务的发展而演进,而不是一开始就追求最先进的技术栈。理解这一点,就理解了架构设计的核心智慧。

一、架构设计的核心理念

非业务功能下沉到基础设施

问题背景

业务代码本身已经足够复杂了,如果一些技术性的代码(例如去重、事务、日志、负载均衡、数据同步)也参与进来,就会显得层次不清晰。

解决方案

把非业务的功能下沉到基础设施层面去实现。例如:

  • 使用 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 来给 updateTime 字段自动赋值,而不是每次写数据时手动赋值
  • 使用数据库的唯一索引来实现去重,而不是在应用层判断

好处

  1. 代码可以专注于业务实现:应用层代码更简洁、更易维护
  2. 更可靠:用基础设施来代替人去实现基础功能更可靠,不容易出错

演进案例

从 Spring Cloud 到 Kubernetes 的演进中可以看到,以前用应用层代码实现的服务发现、负载均衡都被集成到了基础设施层面:

功能 Spring Cloud Kubernetes
服务发现 Eureka/Consul(应用层) Service(基础设施)
负载均衡 Ribbon(应用层) Service + Endpoint(基础设施)
配置管理 Config Server(应用层) ConfigMap/Secret(基础设施)
熔断降级 Hystrix(应用层) Service Mesh(基础设施)

Docker 和 Kubernetes 的成功之道

Docker 的成功

促使 Docker 一问世就惊艳世间的,不是什么黑科技式的秘密武器,而是其符合历史潮流的创意与设计理念,还有充分开放的生态运营。可见,在正确的时候,正确的人手上有一个优秀的点子,确实有机会引爆一个时代。

Kubernetes 的成功

云的时代不能充分利用云的强大能力,这让云计算厂商无比遗憾,也无比焦虑。直到 Kubernetes 横空出世,大家终于等到了破局的希望,认准了这就是云原生时代的操作系统,是让复杂软件在云计算下获得韧性、弹性、可观测性的最佳路径,也是为厂商们推动云计算时代加速到来的关键引擎之一。

成功的关键因素

Kubernetes 的成功不仅有 Google 深厚的技术功底作支撑,有领先时代的设计理念,更加关键的是 Kubernetes 的出现符合所有云计算大厂的切身利益,有着业界巨头不遗余力的广泛支持,它的成功便是一种必然。

启示

技术的成功不仅仅取决于技术本身的先进性,更取决于:

  1. 时机:是否符合历史潮流
  2. 生态:是否有广泛的行业支持
  3. 利益:是否符合关键利益相关方的需求

二、微服务设计

微服务的拆分粒度

粒度的下界(最小应该多大):

微服务至少应满足以下三个条件:

  1. 独立:能够独立发布、独立部署、独立运行与独立测试
  2. 内聚:强相关的功能与数据在同一个服务中处理
  3. 完备:一个服务包含至少一项业务实体与对应的完整操作

失败案例警示

我曾见过一个拆分微服务粒度过细的失败案例:

  • 团队的后端有 5 个人,负责的项目拆成了 6-7 个微服务
  • 服务是分开了可是人还没分开,团队里的每一个人都必须掌握每一个服务的细节
  • 服务之间的依赖关系强到一个改动可能牵扯多个服务
  • 最后还是要用单体架构的思维去开发,没捞到微服务的好处
  • 却付出了微服务的代价,例如原来的 DAO 层的 CRUD 不得不再包装一层上升到 RPC 层面

设计原则

一个服务,它需要对外界暴露细节的越少越好。它所提供的功能应该是简洁且单一的。

粒度的上界(最大应该多大):

微服务粒度的上界是一个 2 Pizza Team(两个披萨能喂饱的团队)能够在一个研发周期内完成的全部需求范围。

团队规模与沟通成本

周老师给出了一个公式,用算法复杂度来理解:沟通成本和团队规模是呈 O(n²) 的关系。一个团队的规模最好限制在 12 人以下(两个披萨能喂饱)。

团队规模 沟通路径数量 管理复杂度
5 人 10 条
10 人 45 条
15 人 105 条
20 人 190 条 极高

三、演进式设计

软件演进的本质

核心比喻

演进式设计与建筑设计的关键区别是,它不像是”造房子”,更像是”换房子”。

生动的例子

  1. 在校求学的你住着六人间宿舍
  2. 初入职场的你搬进了单间出租屋
  3. 新婚燕尔的你买下属于自己的两室一厅
  4. 孩子上学时,你换上了大户型的学区房
  5. 孩子离家读书时,你也终于走上人生巅峰,换了一套梦想中的大别墅

关键洞察

对于你住进大别墅的这个过程,后一套房子并不是前一套房子的”升级版本”:

  • 两套房子之间只有逻辑意义上的继承关系
  • 没有实质血源上的继承关系
  • 你最后的大别墅绝对不是在最初的六人间宿舍基础上添砖加瓦扩建而来的

对软件的启示

大型软件的建设是一个不断推倒重来的演进过程。前一个版本对后一个版本的价值在于:

  1. 它满足了这个阶段用户的需要
  2. 让团队成功适应了这个阶段的复杂度
  3. 可以向下一个台阶迈进

渐进式交付价值

对于最终用户来说,一个能在演进过程中逐步为用户提供价值的系统,体验也要远好于一个憋大招的系统——哪怕这大招最终能成功憋出来。

img

架构腐化与重构

不可避免的现实

无论事先设计得有多么美好,随着需求不断增加和人员的更替,架构的腐化是必然的

解决之道

要保持一个系统正常运转,单纯在原系统上修修补补不能根本解决问题,必须要阶段性地推倒重来

接受不完美

常见的误区

一般来说,我们都很害怕”推倒重来”这个词,因为这往往意味着原先的方案有误,导致先前的工作白费。

正确的认知

  1. 我们不可能在一开始就考虑到以后遇到的所有可能性
  2. 现在的设计只能满足一段时间的需求,在未来它迟早要被替换
  3. 尽管这对于强迫症/代码洁癖者来说是残酷的,但这是现实

阶段性方案的价值

并不是所有软件一开始就要赶时髦用微服务的,在初期,单体架构可能才是最合适的选择:

  • 如果强行使用与需求不符的高级架构,很可能架构本身的复杂度成了开发的最大阻碍
  • 可以等到软件足够复杂时,再进行微服务的拆分,这并不是一种失败

馒头比喻

你吃完第三个馒头才吃饱,这并不意味着前两个馒头是没有意义的。

管理复杂性

复杂性本身不是洪水猛兽,无法处理的复杂性才是。刀耕火种的封建时代无法想像机器大生产中的复杂协作,蒸汽革命时代同样难以想像数字化社会中信息的复杂流动。先进的生产力都伴随着更高的复杂性,需要有与生产力符合的生产关系来匹配,敏锐地捕捉到生产力的变化,随时调整生产关系,这才是架构师治理复杂性的终极方法。

核心观点

概念 说明
生产力 业务复杂度、技术发展
生产关系 架构设计、团队组织
关键能力 敏锐捕捉变化,及时调整架构

四、个人成长与学习

如何判断一个选择的价值

周老师提出了一个价值公式:

价值 = (技能收益 + 知识收益) × 提升空间 / 投入成本

1. 技能收益

能立即派上用场的技能当然是有价值的。首先在社会中务实地生存,不涉及是否快乐,先把本分工作做对做好,再追求兴趣选择和机遇发展。

2. 知识收益

世界上鲜有”烟囱式”的专业人才,专才的知识体系基本还是”金字塔式”的:

  • 在领域里能够显著超过他人高度的前提条件,往往便是拥有着超过他人的知识广度
  • 学习那些并不会立即派上用场的知识的意义:当新的信息输入时,如果能在知识体系中快速找到它应该安放的位置,定位它的问题与解题空间,找到它与其他知识点的关联关系,那你接受新信息的认知负荷就降低了
  • 通俗地讲,你就有了比别人更高的学习效率,更敏锐的技术触觉

3. 提升空间

如果一项工作对你来说是个全新的领域,甚至能称为是一项挑战,那风险的背后往往也蕴含有更高的收益:

  • 如果你真的能把它做出来,这就意味着你的知识体系得到了巨大的拓展
  • 而不是在原来的体系中把五楼加高成六楼

4. 投入成本

权衡思维

在这门架构课程中,我经常讲的一个词是”权衡”,经常说的一句话是”凡事不能只讲收益不谈成本”。在我的价值模型里,收益大小也是必须在确定的成本下才有衡量比较的意义。

成本的构成

这里的成本,既包括你花费的时间、金钱与机会,也包括你投入的知识、精神与毅力。

避免钻牛角尖

如果一项知识或技能,你学习起来非常吃力,花费大力气弄懂之后过一段时间却又会迅速遗忘掉,这很可能是因为:

  1. 你既没有实际应用它的场景
  2. 知识体系中也没有建立好掌握它的稳固的前置基础

取舍策略

  • 这种就属于你目前还拿不动的东西,不妨趁早放手
  • 先做好减法,才能做好加法
  • 也不必觉得可惜,如果它对你来说是必要的,一定还会再次出现,想躲也躲不掉

用输出去倒逼输入

将思考具象化

我所践行的知识整理方法是”将思考具象化”,思考本是外界不可知的,其过程如何、其结果如何只有你自己心里才清楚。如果不把自己思考的内容输出给他人,很容易就会被自己所欺骗,误以为自己已经理解得足够完备了。

输出的重要性

做技术不仅要去看、去读、去想、去用,更要去说、去写。将自己”认为掌握了的”知识叙述出来:

  1. 能够说得清晰有条理,讲得理直气壮
  2. 能够让他人听得明白,释去心中疑惑
  3. 能够把自己的观点交予别人的审视,乃至质疑

在此过程之中,会挖掘出很多潜藏在”已知”背后的”未知”。

周老师的实践

这个目的也是它(凤凰架构)成为免费公益课的原因:课程本身就是我对自己知识体系的整理的成果,是我思考的具象化表现,这件事情中,我自己是最大的受益者,其后的极客时间课程,以及出版的纸质书籍,都可算是额外的收获,这样看来,经济上的回报也就不那么重要了。

启示

  • 输出是最好的学习方式
  • 教是最好的学
  • 写作不仅帮助他人,更是帮助自己梳理知识体系

五、总结

核心观点总结

主题 核心观点 实践建议
基础设施下沉 非业务功能交给基础设施 让代码专注于业务逻辑
技术成功因素 时机 + 生态 + 利益 技术选型要考虑大环境
微服务粒度 2 Pizza Team 能维护的范围 团队规模控制在 12 人以下
演进式设计 换房子而不是造房子 接受阶段性推倒重来
架构选择 适合当前阶段即可 不要过度设计
复杂性管理 调整生产关系匹配生产力 敏锐捕捉变化
个人成长 价值公式指导选择 平衡收益与成本
知识体系 金字塔式而非烟囱式 用输出倒逼输入

读后感悟

《凤凰架构》不仅是一本技术书,更是一本关于软件开发哲学的书:

  1. 没有银弹:所有的架构设计都是权衡的结果,没有完美的方案
  2. 演进而非革命:软件系统应该随着业务发展而演进,而不是一步到位
  3. 适度即可:过度设计和设计不足都是问题,关键是把握当前的复杂度
  4. 持续学习:技术在变化,架构在演进,唯一不变的是学习

周志明老师的文笔流畅,案例生动,将复杂的架构理念讲得通俗易懂。这本书值得所有软件工程师反复阅读,每次都会有新的收获。