我曾经看到过一些文章,开发人员在文章中分享了他们的公司转向面向服务架构(SOA),最后以失败告终又迁移回单体架构的案例。当然,这样做并没有什么错。尝试新架构本来就是我们工作的一部分,看看新架构是否有效,如果无效就放弃。SOA 并不适合所有公司,如果不适合你的公司,那就坚持使用单体架构,如果适合,那就要用对它! 多年来,我们一直使用大单体代码库,于是形成了对某些事情的看法和偏见。如果我们在采用 SOA 时仍然无意识地坚持过去的习惯,可能就意识不到将会在哪些方面遭遇失败。
在本文中,我们将讨论在 SOA 架构中采用单体系统开发实践会存在哪些风险。
想要在 SOA 世界中取得成功,就要避免数据和架构的高度耦合,这点很重要。每一个服务都应该建立在深思熟虑的抽象基础之上。在某种程度上,服务应该是独立的——理想情况下,它们不需要知道其他服务的存在。而在以下这些情况下,很容易创建出高度耦合的服务:
如果不注意,我们可能会得到一个高度耦合的服务生态系统。下面是一些耦合的依赖结构:
左边:服务 A 调用服务 B,知道服务 B 需要调用服务 C,然后它再调用服务 C 获取结果。
右边:服务 A 依赖服务 B,服务 B 依赖服务 C,而服务 C 又依赖服务 A。这是一个依赖循环。
这些结构最终会变成分布式单体。到了某个时候,你会遇到以下这些问题:
“糟糕”的依赖结构是分布式单体的征兆——开发单体的痛苦一点都不会少,面向服务的好处却一点都不会有。此外,高度耦合的服务通常会让你越陷越深。换句话说,如果不解决这些问题,随着服务生态系统的增长,情况会变得更糟。
当数据高度耦合时,你需要使用同步 API 和异步任务来保持数据同步。这些同步过程也可能以 Saga 的形式出现。但不管怎样,你不得不做这些事情:
但是,如果服务生态系统的数据耦合程度很低或者没有耦合,就可以避免这些麻烦。
当你发现自己正处在这样的境地,你该怎么办?当然,并不存在放之四海而皆准的解决方案,这里只是提供一些建议:
在 SOA 世界里,沟通方式、团队、运营、部署和流程与单体架构世界是不一样的。我们开发单体系统使用的工具与开发面向服务系统使用的工具不一定都一样。如果开发人员(和企业)想要成功转向 SOA,那么旧工具和开发习惯也需要被新的工具和开发习惯所取代。
在开发单体系统时,我们在本地机器运行大部分的基础设施。开发人员或多或少都会遇到“它无法在我的机器上运行”的问题。企业会提供引导解决方案来避免这个问题,让开发人员尽快恢复开发工作。大多数解决方案的目标是让基础设施更容易在本地机器上运行。
在开发面向服务的系统时,在本地机器上运行所有的东西将会遇到伸缩性问题。
在本地运行多个服务的解决方案是一种单体思维,以这种方式来开发面向服务的系统可能会变成分布式单体。一些公司提供了本地服务开发解决方案,它们通常是这样的:
端到端测试有两种形式:
单体代码库的端到端测试比较容易。在准备好适当的数据之后,就可以在本地机器上执行测试。
虽然我们已经进行了单元和集成测试,让测试人员在本地机器上进行端到端手动测试仍然会进一步提升我们的信心。随着服务生态系统的发展,服务会越来越多,想要在本地测试所有东西是不可能的事情:
SOA 架构的端到端测试则不太一样。进行本地端到端测试的成本非常高,而且不具备伸缩性。
SOA 之所以流行,是因为它可以加快迭代速度。如果你花了大量时间在本地测试上,那就无法利用 SOA 的优势。你需要放弃在本地测试一切的想法。
你的测试策略取决于你将要采用的本地开发解决方案。下面是一些无需进行本地测试就可以发布代码的方法:
当然,虽然你放弃了本地测试,但仍然可以通过以下这些途径来提升信心:
另一方面,如果测试策略发生了变化,那么调试策略也需要做出改变。
在单体系统中,一个堆栈跟踪信息就足以让我们着手诊断问题。堆栈跟踪信息为我们指明了方向,我们层层深入,直到找到问题根源。堆栈跟踪信息和传统的调试工具通常也可以用来调试 SOA 架构中出现的问题,但对某些问题是毫无用处的:
除了看代码找问题,你的调试工具箱中也需要包括这些:
在采用 SOA 架构时很容易把系统开发成分布式单体。我们要避免将单体系统的开发习惯带到 SOA 架构中。以下是一些需要注意的症状:
单体系统并不是坏东西。很多公司为了转向 SOA 而大肆投入资源,但却没有意识到,在某些情况下,单体可能更适合它们。无论你是坚持使用单体还是采用 SOA,都要避免把系统变成分布式单体——这才是最糟糕的。
原文链接:
https://medium.com/better-programming/signs-of-failing-service-oriented-architecture-fd405c58f75b
领取专属 10元无门槛券
私享最新 技术干货