现代C++软件架构:方法与实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3 单体风格

开发应用程序最简单的架构风格是单体风格,所以许多项目在开始的时候都使用这种风格。单体应用程序像一个大代码块,应用程序功能独立的部分,如I/O部分、数据处理部分和用户界面都是交织在一起的,而不是放在单独的架构组件中。这种架构风格的一个有名的例子是Linux内核。注意,内核是单体的并不妨碍它同时也是模块化的。

部署这样的单体应用程序可能比部署多组件的应用程序更容易,因为只需要部署一个东西。它的测试也更容易,因为端到端测试只需要启动单个组件。它的集成和扩展也都更容易,只需在负载均衡器后面添加更多的实例就行了。

有了上述这些优点,为什么会有人排斥这种架构风格呢?实际上,尽管有这些优点,但这种架构也有许多缺点。

提供的可伸缩性在理论上听起来不错,但是如果应用程序的模块有不同的资源需求呢?只对应用程序中的一个模块进行扩展该怎么做呢?缺乏模块化是单体系统的一个固有特性,这是该架构许多缺陷的根源。

更重要的是,开发单体应用程序的时间越长,在维护时遇到的问题就越多。保持这样一个应用程序的内部松耦合是一个挑战,因为在其模块之间添加额外的依赖关系很容易。随着应用程序的增长,理解它会变得越来越难,因此,由于增加的复杂性,开发过程很可能会随着时间的推移而减慢。在开发单体应用程序时,也可能很难维护领域驱动开发(DDD)的有界上下文。

大的应用程序在部署和执行方面也有缺点。启动这样的应用程序需要的时间比启动更多、更小的服务要长得多。无论你在应用程序中改了什么,你可能都不希望它会迫使你立即重新部署整个应用程序。现在,假设某个开发人员在应用程序中导致了一个资源泄漏。如果泄漏资源的代码被反复执行,它不仅会破坏应用程序的某项功能,还可能会破坏应用程序的其他功能。

如果你喜欢在项目中使用前沿技术,那么单体风格不会带来任何好消息。由于你现在需要一次迁移整个应用程序,因此很难更新任何库或框架。

前面的解释表明,单体架构只适用于简单的小型应用程序。然而,还有一种情况,使用单体架构可能是一个好主意。如果你特别在意性能,与微服务相比,单体服务有时可以在延迟或吞吐量方面帮你挤出更多水分。进程间的通信总是会产生一些开销,而单体应用程序不会产生这些开销。如果你对测量方法感兴趣,请参阅本章“进一步阅读”部分中列出的论文。