案例研究:将结帐系统拆分为太多服务

该项目应该用现代的、可扩展的、松散耦合的实现来取代现有的、单一的、难以扩展的结账系统。 为了实现这一目标,选择微服务架构作为软件系统的目标架构。微服务应该由一些核心服务来编排。此外,还有一个 Javascript 桌面应用程序,具有关联的前端后端(使用核心服务作为主要数据提供者)。服务之间的通信要么通过 HTTP 进行同步,要么在某些情况下通过 MQTP 进行异步。

发生了什么,有转折点或转折点吗?
经过几个月的开发,微服务之间的复杂性开始显着增加,因为对于每个小功能,都需要调整几个服务,并且大多数服务相互依赖。

此外,该架构每次调用至少需要五个 HTTP 或 MQTP 连接,才能访问遗留系统中的数据,而遗留系统仍然是任何类型的合法计算或其他复杂流程的领先系统。

另一个痛点是中央编排服务,它是整个应用程序的单点故障,因为它既不可扩展,也不以最适合此类软件系统的方式实现。

造成了什么不好的后果,为什么一切都不好?
由于单个服务之间的复杂性和依赖性不断增加,速度随着时间的推移而停滞,系统变得不稳定。

第一个大问题是中央编排服务,因为许多必要的功能无法在所选框架中实现。此外,由于核心服务与其他服务或遗留系统之间的数据格式不一致和连接不稳定,与此服务的任何通信都更容易出错。每当整个系统出现故障时,大多数时候都是这个核心服务造成的。

第二个问题是服务之间的依赖性,因为某些“基本”服务或遗留系统适配器的任何更改都会导致基于该服务构建的所有其他服务发生大量更改。因此,对于一个小功能,整个系统都必须进行调整,所有更改的服务必须以正确的顺序同时部署,并且一名开发人员必须在不同的存储库上工作。

这种情况如何解决?
结帐系统需要一致的状态。然而,该系统是作为具有最终一致性的分布式系统实现的。实现最终一致性很难正确,并且通常会导致容易出错且难以维护代码。一种可能的解决方案是将结账系统实现为使用本地交易的“模块”。这个新系统将更容易维护,并且也可以扩展。

“分层主义”也将得到解决,因为应用程序的模块之间不再需要网络调用。这还将使应用程序能够通过使用单个适配器而不是独立的服务来抽象对遗留系统的访问。

错误的决定是由“炒作驱动的开发”造成的,结账系统的功能和非功能需求被部分忽视。

遇到了哪些模式?

  • 过度设计
  • 过度模块化
  • 会议驱动开发
  • 分层主义