架构也是随着其缺陷不断演变而来的,下面是粗略的架构演变史:
70~80s:集中式(大型机)
上世纪70年代和80年代,大型机是计算机的工作方式。
问题所在
:最初的大型计算机使用打孔卡,并且大多数计算都在批处理过程中进行。没有在线处理,并且延迟为100%,因为没有实时处理。
架构演变
:随着在线处理和用户界面终端的推出,大型机范式发生了一些变化。
90s:CS架构(分布式)
客户端/服务器体系结构将大多数逻辑放在服务器端,并将某些处理放在客户端上。
问题所在
:在该体系结构的最初几年中,开发社区仍在使用与大型机开发相同的过程,采用单层原则来为客户端/服务器编写软件,从而产生了诸如意大利面条代码
和Blob
之类的反模式。
架构演变
:引入了一项称为面向对象程序设计(OOP
)的重大改进;
客户/服务器模型基于三层体系结构
,包括展示层,业务逻辑层和数据层。但是大多数应用程序是使用两层模型编写的,胖客户端
将所有展示、业务和数据访问逻辑封装在一起,直接访问数据库。尽管业界已经开始讨论将展示与业务与数据访问分开的必要性,但是这种做法直到基于Internet的应用程序问世才真正变得至关重要。
2000:去中心化(Internet)
在90年代中期,互联网革命发生了,Web浏览器成为客户端软件,而Web和应用程序服务器托管所有处理和逻辑。
问题所在
:开发人员仍在将软件设计为紧密耦合的设计,从而导致混乱和其他反模式。
架构演变
:作为解决办法,业界提出了三层体系结构和实践,例如领域驱动设计
(DDD),企业集成模式
(EIP),SOA
和松耦合
技术。
2006:云托管
21世纪前10年见证了云计算作为服务托管形式的重大改变。应用程序需要的一些能力,云计算平台托管了基础功能:分布式计算、网络、存储以及计算等,与传统的基础架构相比,云托管的方式能更好的控制成本。
问题所在
:它诱使将尚未设计用于弹性分布式架构的遗留应用程序直接迁移和迁移到云中,从而产生了单体地狱这种反模式。
迁移到云还给行业带来了管理第三方库和技术上的应用程序依赖项的挑战。没有足够的标准来选择第三方工具,我们开始看到一些依赖地狱。另外服务扩容也是一个问题。
架构演变
:了应对这些挑战,业界提出了新的架构模式,例如微服务
和12要素应用程序
[1],弹性服务
。
2014:微服务
诸如DDD
和EIP
之类的软件设计自2003年左右就已经开始实践起来了,此时一些团队将应用程序开发为模块化服务,但是传统的基础结构(如Java应用程序的重量级J2EE应用程序服务器和.NET应用程序的IIS)对模块化部署并没有帮助。
随着云托管的出现,尤其是诸如Heroku和Cloud Foundry之类的PaaS产品的出现,开发人员社区拥有了真正的模块化部署和可扩展业务应用所需的一切。这引起了微服务的发展。微服务为打造细粒度、可重用的功能和非功能服务提供了可能性。
问题所在
:原本的单体系统、未被设计为微服务的传统应用程序开始被蚕食,试图迫使它们进入微服务体系结构,由于拆解的不当,从而导致了被称为微单体的反模式。单体和微服务是两种不同的模式,后者并不总是可以替代前者。如果我们不小心的话,最终可能会创建紧密耦合,混杂的微服务。微服务剧增的另一个不希望出现的副作用是所谓的“死亡星球”的反模式。
架构演变
:诸如服务网格,边车,服务编排和容器之类的新兴架构模式可以有效地防御基于云的世界中的渎职行为。随着云平台的出现,特别是像Kubernetes这样的容器编排技术,服务网格已经引起了人们的关注。服务网格是应用程序服务之间的桥梁,可添加其他功能,例如流量控制,服务发现,负载平衡,弹性,可观察性,安全性等。
几种架构反模式[2]说明
单体地狱
[3]:- 好处:早期开发简单、易于对程序做重大更改、直接测试、直接部署、易于扩展;
- 缺点:随着业务增长,暴露问题:复杂度高、开发效率低下、从提交到部署耗时长、伸缩性差、技术栈过时难以升级、缺乏故障隔离导致一个小功能可能会影响整个系统;
微单体
[4]:- 一种非弹性和不可扩展的微服务系统,即所谓的微单体;单体和微服务是两种不同的模式,后者并不总是可以替代前者。如果我们不小心的话,最终可能会创建紧密耦合,混杂的微服务(微单体)。我们应该根据应用程序功能的业务和可伸缩性要求做抉择;
积木塔
:单体应用程序类似于积木塔:您永远不知道发生故障时哪块砖可能会出问题。由于该应用程序的所有模块都在同一进程中运行,因此,如果某个模块受到错误的影响,则会降低整个过程,从而影响整个应用程序。 在完成故障排除之前,您可能会失去数百甚至数千个商机;科学怪人
[5]:科学怪人是一部著名的美国电影,讲述了一个天才科学家创造了一个怪物最终被其毁灭的故事。Istio 团队为以它来自嘲。Istio 本想扮演上帝一般的角色(统一 Service Mesh 江湖,成为微服务架构的事实标准),却因为过度设计与现实脱离,成为了一个怪兽(monster)。因此,重构的第一阶段,就是从肢解怪兽开始,把微服务架构重新改回了单体架构,但是内部模块划分还是很清晰的;方轮
:重新发明方的轮子,已经有了一个很好的方案,又搞一个方案来替代它;死亡星球
[6]:- 在服务交互和服务到服务的安全性(身份验证和授权)方面,如果没有治理模型,微服务的泛滥通常会导致任何服务都可以随意调用任何其他服务的情况。就有可能出现想死亡星球那样的调用视图,异常复杂。诸如服务网格,边车,服务编排和容器之类的新兴架构模式可以有效地防御基于云的世界中的渎职行为;
意大利面条式的设计
:面条之间互相缠绕在一起,很难梳理清楚它们之间的关系。意大利面式的设计很形象的说明了软件开发中的这种现象:系统很难维护,各种功能逻辑缠绕在一起,没有清晰的模块和层次关系;The Blob
:表示的是一个类型具有了过多的职能,导致其过于庞大,最后使代码难以维护。
架构演变步骤
一般的,每一个架构的出现,不是一蹴而就的,都会经历以下几个过程:
- 引入新模型;
- 最佳架构实践未知或者不存在;
- 反模式,技术债务剧增;
- 行业开发新的体系结构以适应新的范式;
- 团队研究并采用新的标准架构;
下面我们将于Java工程师
的角度来观察架构的大致发展史。