云原生应用开发实战:基于.NET开发框架及Kubernetes容器编排技术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1.1 单体应用面临的挑战

不过,到了某个时间点上,你开始感到有点不舒服了。你发现你已经对应用失去了控制。随着时间的推移,这种感觉变得更加紧迫,你不可避免地陷入了称为恐惧循环的状态。

● 应用程序变得非常复杂,以至于没有一个人可以完全理解它。

● 你害怕做出改变——每个改变都有意想不到并且代价高昂的副作用。

● 增加新功能或者修复Bug变得很棘手,耗时且成本高昂。

● 每个版本更新都变得尽可能小,并且需要完全部署整个应用程序。

● 一个不稳定的组件可能会使整个系统崩溃。

● 无法引入新的技术和框架。

● 实施敏捷交付方法变得非常困难。

● 各种不同风格的修补不断侵蚀着架构,应用变得越来越脆弱和难以理解,没有人愿意再继续维护它。

这些是不是听起来很熟悉?这个庞大的单体应用,由于开发人员的更迭,需求的不断变化,慢慢显露出各种疲态。

1.代码臃肿

应用程序本身是有生命的,其潜在的发展趋势是,随着时间推移而变得越来越臃肿,开发团队在每个冲刺阶段都要实现更多的用户需求,这意味着需要添加了许多行的代码。数年之后,小而简单的应用将会逐渐变成一个庞大的单体应用。

2.开发困难

一旦产品成为一个庞大、复杂的单体应用,开发团队就会陷入了一个痛苦的境地,对敏捷开发和交付的尝试变得难以推进。主要问题是应用程序变得实在非常复杂,对于任何一个开发人员来说,都显得过于庞大且难以理解。最终,高质量地修复Bug和实现新的功能变得非常困难而且耗时,这种趋势就像是死亡螺旋。如果连最为基本的代码都令人难以理解,那么对软件的改进也就难以保证质量,终将得到的是一个高耸入云但是脆弱的危楼。

3.限制发展

应用程序的规模变得越庞大,开发或者运维人员重新启动应用所需要的时间就变得更长。很大一部分时间都将在等待中度过,而这样的时间浪费将会极大的影响和阻碍业务的发展,将开发人员的耐心消耗殆尽,最终将有可能导致公司失去市场机会。

4.持续部署困难

复杂的单体应用本身就是持续部署的障碍。

在当前的技术环境下,SaaS(Software as a Service,软件即服务)应用已经发展到了可以每天多次将变更推送到生产环境中,而这种需求对于复杂的单体应用来说非常困难,因为它需要重新部署整个应用程序,才能完成更新其中的部分功能,同时还需要在应用部署后经过漫长的等待启动的时间,等待应用程序初始化启动完成。

此外,因为难以确认因部署变更所产生的影响,在很多情况下还需要做大量的手工测试。因此,单体应用非常难以与持续部署相结合。

5.扩展困难

当不同业务模块存在资源需求冲突时,单体应用可能难以扩展。例如,其中一个模块可能会执行CPU密集型的图像处理逻辑,理想情况下是部署在计算能力优化的环境中,而另外一个模块可能是一个内存数据库,它适合部署到更大内存的环境中。然而,由于这些业务模块深度耦合在一起,导致必须在硬件选择上做出妥协。

6.可靠性差

由于单体应用所有的业务、功能模块都运行在同一个进程中,导致其中任何一个模块的Bug(例如内存泄漏)都有可能会拖垮整个进程,导致应用程序的所有业务都不可用。

7.重构困难

单体应用使得采用新的技术框架和语言变得非常困难:假设有一个包含了200万行代码的应用使用框架A构建,想要迁移到新出现的优秀的框架B上,时间与资源成本的消耗是极其恐怖的。

因此,单体应用是采用新技术的巨大障碍,这也导致在项目开始时,无论选择任何新技术都会对整个项目的开发与交付产生巨大的影响。

当一个原来成功的关键业务应用程序,慢慢发展成一个只有少数开发人员(如果有的话)能够理解的巨大单体应用,它还使用了过时的、非当前主流的技术开发,这使得招聘更加优秀的开发人员变得非常困难、应用程序也变得难以扩展、不可靠。

因此单体应用想实现敏捷开发和快速应用交付是不可能的。