(转)5、单体架构

翻译转帖

原文链接 https://herbertograca.com/2017/07/31/monolithic-architecture/

这篇文章是软件架构编年史的一部分, 这是一系列关于软件架构的文章。在它们中,我写了我在软件架构方面学到的东西,我如何看待它,以及我如何使用这些知识。如果您阅读本系列之前的文章,这篇文章的内容可能会更有意义。

一开始,有巨石…… 

构建单体应用一直是默认的架构风格。我的意思是,一开始我们每个应用程序有一个文件,然后我们开始有包含多个文件的应用程序,直到 1990 年代我们才开始看到由其他应用程序组成的应用程序(尽管第一次实验是在 1980 年代)。

巨石本身是进化而来的。当开始使用多个文件构建应用程序时,没有太多关于它们的推理,也没有很大的必要性,因为应用程序相对简单。随着应用程序变得越来越大和越来越复杂,需要在创建什么文件以及如何将它们关联的背后进行一些推理。

模块化软件开发

模块化编程是 1960 年代后期和 1970 年代提出的解决方案。这是从类到更粗粒度的代码单元显式定义的演变。编程语言以不同级别的显式实现模块化。

例如,JAVA 具有defaultpublic 的类级别可见性,其中default级别表示类仅在其包(模块)中可见,而public表示该类在其包(模块)内外可见。这允许我们定义包的客户端应该使用哪些类。

组件化软件开发

另一种模块化风格是组件。正如我在之前的一篇博文中解释的那样,组件是在考虑领域概念的情况下创建的模块。它们是理想的独立“应用程序”,可用于创建复合应用程序。如果管道和过滤器体系结构在 Unix 系统中广泛使用,并且允许我们执行诸如“ ps -ef | grep php ”。另一个例子是使用微服务作为复合应用程序的组件,如 Netflix。

这种代码组织方式也已经存在很长时间了,可以追溯到 1960 年代后期,就像模块化软件开发一样。

现代单体

如今,拥有单体架构风格只是意味着所有应用程序代码都作为单个进程在单个节点上部署和运行。我们假设它正在使用模块和组件,尽管实际上通常并非如此。

理解为什么这里的关键词是“部署”和“节点”很重要。关于第一个,已部署,这意味着如果将代码组织在一个或多个存储库中,它的物理存储位置并不重要,重要的是它在运行时如何组织。关于第二个关键字node,这意味着如果我们将应用程序部署到多个服务器,它仍然是一个整体,就像在水平扩展上下文中一样。

在单节点服务器中,单体应用中的所有模块都组装到同一个内存映像中,该映像在单个节点上作为单个进程运行。通信是通过相同的堆栈和堆通过标准过程调用完成的。单个内存映像使应用程序成为整体。如果你在不同的进程中运行模块,你就是在做 IPC。由于模块属于不同的进程边界,您将开始面临分布式计算挑战。这正在进入微服务领域。(感谢您的反馈,  _dban_)

这种风格虽然名声很差,但即使对于大型应用程序也能很好地工作。只有当我们需要时,它才会变得足够好:

  • 不同域组件的独立可扩展性
  • 不同的组件或模块要用不同的编程语言编写;
  • 独立的可部署性,可能是因为我们的发布率高于部署管道可以处理的一个代码库,导致一个版本的部署缓慢,因为它需要等待其他版本的部署,甚至导致部署队列增长速度快于消耗。

在这一点上,我们需要以 SOA 架构风格将我们的单体应用分离到不同的应用程序中(更多内容在后续文章中)。

反模式:大泥球 / Spaghetti Architecture

“大泥球”,AKA Spaghetti Architecture,是这种风格的反模式,其中包结构和关系不明确,结构内聚和封装不存在或很小,依赖不遵循规则,非常难以推理子系统、进行更改和重构。该系统是不透明的粘稠的脆弱的僵硬的:一个大泥球

来源

1997 年——布赖恩·富特、约瑟夫·尤德——大泥球

2012 年 – Len Bass、Paul Clements、Rick Kazman – 实践中的软件架构

2017 – Herberto Graça – 微服务架构:大师们怎么说

2017 – Herberto Graca – 软件架构前提

2017* – 维基百科 – 模块化编程

2017* - 维基百科 - 基于组件的软件工程

你可能感兴趣的:(软件架构,软件架构)