这篇文章是 软件架构编年史的一部分,这是一系列关于软件架构的文章。在其中,我写下了我在软件架构方面学到的知识、我对它的看法以及我如何使用这些知识。如果您阅读了本系列的前几篇文章,这篇文章的内容可能会更有意义。
一开始,有巨石……
构建单体一直是默认的架构风格。我的意思是,一开始我们每个应用程序有一个文件,然后我们开始有多个文件的应用程序,直到 1990 年代我们才开始看到由其他应用程序组成的应用程序(尽管第一次实验是在 1980 年代)。
巨石本身也在进化。当开始使用多个文件构建应用程序时,没有太多关于它们的推理,也没有很大的推理需求,因为应用程序相对简单。随着应用程序变得越来越大和越来越复杂,需要对创建哪些文件以及如何关联它们进行一些推理。
模块化软件开发
模块化编程是 1960 年代后期和 70 年代提出的解决方案。这是从类到更粗粒度的代码单元显式定义的演变。编程语言实现了具有不同等级明确性的模块化。
例如JAVA有类级别的可见性default和public,其中default级别表示一个类只在其包(模块)内可见,public表示该类在其包(模块)内外可见。这允许我们定义包的客户端应该使用哪些类。
组件化软件开发
另一种模块化风格是组件。正如我之前的一篇文章中所解释的,组件是在考虑领域概念的情况下创建的模块。它们是理想的独立“应用程序”,可用于创建复合应用程序。这种风格的一个反复出现的例子是管道和过滤器架构,在 Unix 系统中广泛使用,它允许我们做类似“ ps -ef | grep php ”。另一个例子是将微服务用作复合应用程序的组件,例如 Netflix。
这种代码组织风格也已经存在了很长时间,可以追溯到 1960 年代后期,就像模块化软件开发一样。
现代巨石
如今,拥有单体架构风格仅意味着所有应用程序代码都作为单个进程在单个节点上部署和运行。我们假设,它正在使用模块和组件,尽管实际上通常并非如此。
重要的是要理解为什么这里的关键词是“已部署”和“节点”。关于第一个,deployed,这意味着如果将代码组织在一个或多个存储库中,代码物理存储在何处并不重要,而是在运行时如何组织。关于第二个关键字node,这意味着如果我们将应用程序部署到多个服务器,它仍然是一个整体,就像在水平扩展上下文中一样。
在单节点服务器中,单体中的所有模块都组装到同一内存映像中,该内存映像作为单个进程在单个节点上运行。通信是通过相同堆栈和堆的标准过程调用完成的。它是单个内存映像,使应用程序成为整体。如果您在不同的进程中运行模块,那么您就是在进行 IPC。由于模块属于不同的进程边界,您将开始面临分布式计算的挑战。那就是进入微服务领域。(感谢您的反馈, _dban_)
这种风格虽然声誉很差,但即使对于大型应用程序也能很好地工作。它只有在我们需要时才不再足够好:
- 不同领域组件的独立可扩展性;
- 用不同的编程语言编写不同的组件或模块;
- 独立可部署性,可能是因为我们的发布速率高于部署管道可以处理的一个代码库,导致一个发布的部署很慢,因为它需要等待其他发布的部署,甚至导致部署队列增长速度快于消耗速度。
在这一点上,我们需要以 SOA 架构风格(在后续帖子中详细介绍)将我们的单体分成不同的应用程序。
反模式:大泥球/意大利面条架构
“大泥球”,AKA Spaghetti Architecture,是这种风格的反模式,其中包的结构和关系不明确,结构内聚和封装不存在或很少,依赖性不遵循规则并且非常很难对子系统进行推理,进行更改和重构。该系统不透明、粘稠、脆弱且坚硬:一个大泥球!
参考资料:https://herbertograca.com/2017/07/31/monolithic-architecture/
本文暂时没有评论,来添加一个吧(●'◡'●)