好书推荐 - 《分布式系统应用设计》
作者简介
Brendan Burns,微软 Azure 的杰出工程师,也是 Kubernetes 开源项目的共同创始人。在加入微软之前,他曾在谷歌云平台工作,帮助构建了 Deployment Manager 和 Cloud DNS 等 API。
内容简介
容器及其编排系统的快速发展极大地改变了分布式系统的开发和部署方式,从此,我们有了全新的方式与接口来描述核心分布式系统的开发模式及可重用的容器化组件。作为一本指导性手册,《分布式系统应用设计》主要介绍了常见的可重用的设计模式,以帮助开发人员更高效地开发可靠的分布式系统。
之前开发者经常不得不从头开发系统,导致每个系统架构看起来都各不相同。
《分布式系统应用设计》作者展示了如何利用现有的、验证过的设计模式来构建可靠的分布式系统。对于系统工程师和应用开发者而言,可以从中学习如何借助设计模式强大的语言和框架表征优势来显著提高工程质量。
深入理解设计模式和可重用组件如何帮助开发者开发可靠分布式系统。如何借助边车、适配鬻和大使模式在单机环境中将功能分解成为一组容器。掌握多节点常见的松耦合模式,以实现复制、扩展和组件之间的通信。学习大规模批处理设计模式,如工作队列、基于事件的处理和协调工作流程。
评价
豆瓣:https://m.douban.com/book/subject/34844678/
知乎:https://zhuanlan.zhihu.com/p/105307751
简述
如同 Akka 的 Tech Leader 写出来的《反应式设计模式》实际上大部分是 Effective Akka 一样,这本 Kubernetes 的 cofounder 写出来的《分布式系统应用设计》更应该叫做《设计模式:构建基于 Kubernetes 的分布式系统》。
不过如果将本书看做一本 Kubernetes 的实践指南,那么它的内容又未免过于单薄。正文不足 150 页的内容涉及实践的部分也仅仅是蜻蜓点水一般的带过。那么本书的价值在哪儿呢?本书的价值主要在于揭示了设计模式的发展历程和设计模式本位的软件开发进化史,以及近年来 Kubernetes 社区在开发基于 Kubernetes 或者说云原生的分布式应用上沉淀的优秀实例。
设计模式的发展历程
本书开篇就讨论了系统开发的发展历程,指出【这已经不是第一次在软件行业发生这样的转变。为了更好地理解模式、实践和可重用的组件是如何重塑以前的系统开发的,审视类似转换发生的历史是很有帮助的】。
书中将设计模式的发展分为三个阶段。
其一是算法编程的阶段,代表作是《计算机程序设计艺术》。算法编程的设计模式为用户提供了用于构建程序的共享工具包(Toolkit),同时也表明存在一种开发者应该学习并随后可以应用于各种不同上下文的通用概念。独立于任何待解决的具体问题,算法本身就值得了解。
其二是面向对象编程的阶段,代表作是《设计模式:可复用面向对象软件的基础》。面向对象的设计模式为编程任务提供了通用的语言(Unique Language)和框架(Framework),它描述了一系列基于接口的模式,可以在各种环境中重用。由于面向对象编程的发展和特定的接口,这些模式也可以实现为通用的可重用库。这些库可以由社区的开发人员编写一次并重复使用,从而节省时间并提高可靠性。
其三就是作者这本书想要介绍的分布式系统的设计模式,它将以容器和容器编排为基础,建立一套模式和可重用组件。这些模式和组件将用于更可靠、更有效地构建分布式系统的基础。显然,以容器和容器编排为基础意味着这些设计模式是为了构建云原生的分布式应用而存在的。
目前分布式系统的发展还远远未到一个标准统一天下的阶段。云原生的分布式应用作为当下热点,并且经受了生产环境一段时间的考验,了解其社区的沉淀对于开发者的自我提升和迎接技术浪潮是有益的。至于未来的软件开发是否会走向云原生的分布式应用主导,这一点恐怕还不是板上钉钉的。
无论如何,书中提及的模式,实践和组件的价值是恒常的。设计模式能够指导你在开发相应的软件的时候辨认和采用久经考验的最佳实践,帮助你构建复杂系统。同时,它提供一组通用的名称和定义,避免开发者讨论时争论名称不同的两个实质相同的内容。最后,以模式为基础,社区可以定义和开发出一整套可重用的组件。这些组件将被同于构建更复杂的系统。这样一种设计模式本位的软件开发进化史的观点能够帮助处于入门但不精进的开发者综合的考量现有的技术,建立起自己整合不同技术和分析真实世界的软件系统的主轴。
云原生分布式应用的前车之鉴
本书从设计模式方面分为容器组(Pod)内不同容器的单节点模式和集群环境下的服务模式,第三部分的批处理计算模式我理解跟云原生关系不大,内容也很一般,属于比较强行的篇章,这里略过不表。
单节点模式说白了就是在同一容器组内组合不同的容器的策略。两个同等层级的容器的交互是完全业务主导的,因此本书中也未做探讨。本书主要讨论的是有明显的应用程序容器和辅助容器的区分时的容器之间的组合。总的来说,根据应用程序容器对外访问,接收外部访问和双向处理访问分成了大使模式,边车模式和适配器模式。其实都是某种意义上的适配器模式。
这里需要重视的是边车模式,即应用程序逻辑单独跑在一个容器内,外部对应用程序容器的访问经过边车容器的修饰到达应用程序容器。这种模式可以在不侵入应用程序的情况下将大量的应用程序逻辑组合在同一个系统中。一个成功的例子就是服务网格的解决方案 Istio,在 Istio 中边车模式被广泛的采用。
服务模式是走向分布式系统的必经之路。这是因为为了可靠性、可扩展性,以及关注点分离等目标,现实中大型系统往往是由多个不同组件联合构建的,并且服务分布在多台机器上。本书主要讨论了无差别副本的负载均衡模式,请求分发的分片服务模式,计算分发的分散聚集模式,事件驱动处理的 FaaS 模式和多节点服务模式中的所有权选举策略。
前三者关注在如何将请求合理的分配到不同的服务器上。其中负载均衡是早在 Kubernetes 出现之前就已经非常成熟的概念,分片服务则是数据库领域一个常见的话题,而书中命名的分散聚集模式更像是应用层面对经典的 MapReduce 模式的另一种说法。
功能即服务(FaaS)是近几年来逐渐兴起的一个新概念,它将应用程序逻辑抽象为事件触发执行一定逻辑的单个函数,应用程序开发者只需要根据服务提供方提供的接口编写相应的业务逻辑,服务提供方会负责将这个逻辑作为黑盒函数部署到底层的平台或说服务器中运行。这个流程中开发者无需自己负责部署和发布的流程,几乎看不到服务器的存在,因此被称为无服务器的(Serverless)计算。书中介绍了 FaaS 的主要挑战,包括微服务的一生之敌服务拆分,FaaS 模式下的计费方案及带来的开发思路的转换,以及 FaaS 不适用的应用程序的特征。
所有权选举策略介绍了在分布式环境下所有权分配或者直接地说主节点选举的常用方法和常见问题。某种程度上,分布式所有权问题堪称可靠分布式系统设计中最复杂,又最重要的部分。本书详细的介绍了主节点选举中不同节点挨个崩溃最终让你崩溃的五花八门的情况。即使使用了 ZooKeeper 或者 Etcd 这样的分布式共识系统,它们也只是在系统设计的范围内提供一定的原语级别的一致性保证。要使用这些原语构建出应用程序层面的所有权一致性,你就要面对极端情况下按任意时序崩溃的节点。书中【处理并发操作】一节介绍了非拜占庭式故障的极度恶劣的边界情况。对于需要实现分布式系统一致性的开发者来说,本书虽然没有介绍具体的解决方法,但是明白你将面临一个多么可怕的问题是非常重要的。这一部分的扩展材料可以阅读 Heidi Howard 的博士论文《Distributed consensus revised》(https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-935.pdf)。