第2章 微前端原则
记得在职业生涯的初期,我在一些中小型团队中开发过很多软件项目。在软件开发过程中,这些团队会完成一个集成了平台的所有业务功能的单体应用,并将生成的产品部署到 Web 服务器上。
如果想在一个单体应用里让大量代码和谐地运行,根据我的经验,需要针对程序逻辑进行预先的优化和复杂的工程化设计,但是对可复用代码的抽象化会导致代码库更加复杂。从长远看,维护复杂代码逻辑的努力是不会有什么回报的。更不幸的是,有些在当时看起来简单直接的东西,几个月后会变得笨重不堪。
在过去的十年中,AWS、Google Cloud 等公有云服务提供商日益获得关注,因为它们通过越来越多的商业授权让许多机构关注商业活动中真正重要的东西,那就是提供给最终用户的服务。
虽然云服务系统能够使用更简单的方式扩大我们的工程规模,但遗憾的是,单体应用无法单独伸缩某一块业务,必须全量实施。如果系统代码的编写质量不高,或者模块化不足,就会让人非常头疼。
此外,分散的团队和协同的团队一起维护单体应用代码库是有挑战性的,特别是在团队规模达到中大型以后,这种挑战更加明显,因为沟通成本会很高,少数人要替所有人做决定。
长期来看,一些公司在维护大型单体应用时,很难对新功能的迭代提供快速的支持,因而失去了在项目初期所展现的强大动力,毕竟一开始的系统复杂度和风险比较小,出现的问题比较简单。而且,对于单体应用,我们必须每次都部署整个代码库,这就增加了在生产环境中破坏 API、引入新 bug 和犯更多错误的可能性,尤其是在代码库并非坚如磐石时,或没有经过广泛测试时。为了解决员工面临的这些问题,应对其他挑战,公司可能会将复杂的单体应用代码库拆分成多个小型代码库和作用域,这些被称为微服务。
如今,微服务广为人知,它是一个被全世界很多机构使用的模式。微服务将一个独立的代码库分割成更小的部分,与单体方案相比,每一部分只是一个子功能集,每个部分都相互独立,这使得团队对代码库拥有完整的管理权并能够进行独立的代码迭代。微服务的业务逻辑之所以受到开发人员的欢迎,是因为对于开发人员来说,比起在单体架构中面对数千行的代码,微服务模式要简单得多。与处理单体代码库相比,它确实降低了团队的认知负荷。
微服务的另外一个显著优势是可以扩展应用程序并采用适合当前功能集的方法,而不像单体应用那样采用“一刀切”的方式。但是,采用微服务也有一些缺点。我们必须在自动化、可观察性以及监控性方面有所投入,才能实现一个可控的分布式系统。另外一个缺点是容易对微服务边界做出错误的界定,比如在一个依赖其他微服务的系统中存在一个不足以完成一项操作的过小微服务,它造成了服务之间的强耦合,这使得开发人员不得不每次都将它们一起部署。当这种现象扩展到多个服务时,我们可能面临的结果就是一个复杂到难以扩展的系统,一个杂乱无序的“大泥球”。
微服务带来了很多好处,但也带来了很多弊端。当我们在项目中使用微服务时,微服务架构的复杂性可能只会带来痛苦,而非益处。软件开发可选的架构有很多种,我们应该只在必要的时候选用微服务,而不是仅仅因为它是最新的、最好的实现方式而草率地选用它。
近来兴起的微前端和过去我们在 Web 开发中所用的单体方案截然不同,它重新定义了软件交付和任务边界。要记住,无论是微服务还是微前端,它们都不是分解软件的通用方法。为了理解它们适用于何种场景,明白它们到底是什么,让我们看看是什么让我们选择了微前端。