01 原始分布式时代:Unix设计哲学下的服务探索

140 阅读7分钟

架构并不是被“发明”出来的,而是持续进化的结果

Unix的分布式设计哲学 保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性和完整性,都来的更加重要

分布式架构的模板是使用多个独立的分布式服务,来共同构建一个更大型的系统。与绝大多数人心中的认知有差异,分布式系统的设想和它实际的尝试,比今天所了解的大型单体系统出现的更早。


在20世界70年代末到80年代初,计算机经历了从大型机为主,到以微型机为主的蜕变。这时候的微型计算机硬件的运算处理能力还相对薄弱,已经直接妨碍了单台计算机上信息系统软件能够达到的最大规模。为了突破硬件算力的限制,各个高校、研究机构、软硬件厂商都开始分头探索,能不能用多台计算机共同协作,来支撑同一套软件系统的运行。这个阶段其实是对分布式架构最原始的探索和研究。

从结果来看,半个世纪之前的研究没有一蹴而就地解决分布式的难题,但从过程来看,这个阶段的探索可以称得上硕果累累、成绩斐然。这个时期提出的很多技术、概念、对unix系统后续的发展都产生了巨大而深远的影响,直接带动了后续的软件架构演化过程。

比如惠普公司提出的网络运算架构,就是未来远程服务调用的雏形;再比如卡内基·梅隆大学提出的AFS文件系统,可以看作是分布式文件系统的最早实现;再比如麻省理工学院提出的Kerberos协议,是服务认证和访问控制(ACL)的基础性协议,是分布式服务安全性的重要支撑。


为了避免Unix系统的版本战争在分布式领域重演,OSF(负责制定Unix系统技术标准的开放软件基金会)邀请了各个主要的研发厂商一起参与制订了DCE(分布式运算环境的分布式计算体系)

DCE包括了一整套完整的分布式服务组件的规范和实现 比如源自NCA的远程服务调用规范,基于通用TCP/IP协议的远程服务标准,一起被认为是现代RPC的共同鼻祖。源自AFS的分布式文件系统;源自Kerberos的服务认证规范;时间服务;命名和目录服务;通用唯一标识符UUID。都是DCE中发明出来的。


研究分布式计算,通常都会用一个预设的重要原则

实现分布式环境中的服务调用、资源访问、数据存储等操作的时候,要尽可能地透明化、简单化,让开发人员不用去过于关注他们的方法,或者是要知道其他资源是位于本地还是远程。

但这个目标其实是过于理想化,它存在一些当时根本不可能完美解决的技术困难。先不说远程方法不可能做到像本地方法一样,能用内联等传统编译原理中的优化算法,来提升程序运行速度。

光是“远程”带来的网络环境下的新问题。比如远程的服务在哪里(服务发现)、有多少个(负载均衡)、网络出现分区、超时或者服务出错怎么办(熔断、隔离、降级)、方法的参数和返回结果如何表示(序列化协议)、如何传输(传输协议)、服务权限如何管理(认证、授权)、如何保证通信安全(网络安全层)、如何令调用不同的机器的服务都能返回相同的结果(分布式数据一致性)等问题。

面对重重困难,DCD不仅从零开始、从无到有地回答了其中大部分问题,构建出了大量的分布式基础组件和协议,而且它还真的尽力去做到了相对一样的“透明”


分布式和本地在性能上还是有很大的差距。在机器硬件的限制下,开发者为了让程序在运行效率上可以接受,就只有在方法本身的运行时间很长,可以相对忽略远程调用成本的情况下,才去考虑使用分布式。

如果方法本身的运行时间不够长,就要人为地用各种奇技淫巧来刻意构造出这样的场景,比如可能会将几个原本毫无关系的方法打包到一个方法内,一块进行远程调用。

一方面,可以构造长时间运行的方法这本身就与使用分布式来突破硬件算力、提升性能的初衷相互矛盾。另一方面,此时的开发人员,实际上仍然必须无时无刻地都要意识到,自己是在编写分布式程序,不能随随便便地踏过本地和远程的界限,让DCE“尽可能简单透明”的努力几乎全部付之东流。

因为本地和远程,无论是编码、部署、还是从运行效率的角度上看,都有天壤之别,所以在设计一个能运行良好的分布式应用时,就变得需要极高的编程技巧和各方面的知识来作为支撑,这时候,反而是人员本身对软件规模的约束,超过了机器算力上的约束。

某个功能能够进行分布式,并不意味着他就应该进行分布式,强行追求透明的分布式操作,只会自寻苦果。


在当时计算机科学面前,有两条通往更大规模软件系统的道路,一条路是尽快提升单机的处理能力,以避免分布式的种种问题;另外一条路是找到更完美的解决方案,来应对如何构筑分布式系统的问题

在20世纪80年代,正是摩尔定律开始稳定发挥作用的黄金时期,微型计算机的性能以每两年增长一倍的惊人速度在提升,硬件算力约束软件规模的链条开始松动了。用单台或几台计算机就可以作为服务器来支撑大型信息系统的运行,信息系统进入了单体时代,而且在未来很长一段时间内,单体系统都是软件架构的主流。


一课一思


“保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性和完整性,都来得更加重要。” 现在你来思考一下:今天以微服务为代表的分布式系统,是如何看待“简单”的?


“简单”需要从两个方面来看待,分别是业务和技术。

业务:现代软件系统的业务复杂性越来越高,而分离关注点是应对日益增长的业务复杂性的有效手段。但如果依旧是一个大单体系统,那么跨业务单元的知识需求就很难避免,并且开发迭代和版本发布中还会彼此影响。微服务的出现为其提供了设定物理边界的技术基础。使得多个特性团队对业务知识的诉求可以收敛在自身领域,降低单个特性团队所需了解的业务知识。

技术:就像rpc让开发者像调用本地方法一样调用远程方法,微服务技术的出现,是为了让开发者可以基于意图去使用各种分布式系统的工具,而不用深入具体工具的实现细节。

最后再补充,微服务的生态已经不局限开发阶段。在部署和运行阶段都有健全组件支持。可以让开发者基于意图就可以简便的实现金丝雀发布。

在整个“演进中的架构”这部分,一条重要的逻辑线索就是软件工业对如何拆分业务、隔离技术复杂性的探索。从最初的不拆分、到通过越来越复杂的技术手段满足业务的拆分和协作,再到追求隔离掉这些复杂计算手段,将他们掩埋到基础设施之中。到未来重新回到无需考虑算力,无需拆分的运行系统