想象一下,我们有2项服务:产品和订单。基于我对SOA的理解,我知道每个服务都可以拥有自己的数据存储(一个单独的数据库,或同一个数据库中的一组表)。但是,不允许任何服务直接触摸另一个服务的数据存储。
现在,假设我们已在产品和订单服务中独立存储产品和订单数据。在订单服务中,我们可以通过其ID识别产品。
我的问题是:使用此架构,如何在“同一”页面上显示订单列表和产品详细信息?
我的理解是我应该从OrderService获取OrderItems列表。每个OrderItem都有一个ProductID。现在,如果我单独调用ProductService来检索有关每个产品的详细信息,那将是非常低效的。
你会如何解决这个问题?
干杯, MOSH
答案 0 :(得分:12)
我做了一些研究,发现了2种不同的解决方案。
1-服务可以在本地缓存其他服务的数据。但这需要pub / sub机制,因此应该发布数据源的任何更改,以便订阅服务可以更新其本地缓存。实施起来成本很高,但是最快的解决方案是因为服务在本地具有所需的数据。它还通过防止服务依赖于其他服务的数据来提高服务的可用性。换句话说,如果其他服务不可用,它仍然可以通过其缓存数据完成其工作。
2-或者,服务可以通过提供标识符列表来查询来自另一个服务的对象的“列表”。这可以防止对目标服务进行单独调用以获取给定对象的详细信息。这更容易实现,但在性能方面,并不像解决方案1那么快。此外,如果目标服务不可用,源服务无法完成其工作。
希望这有助于遇到此问题的其他人。
MOSH
答案 1 :(得分:3)
数据库集成(当两个服务在数据库中共享一个表时,你真正在谈论的是这么多级别的错误)! 它彻底打破了软件工程的一些主要原则
松耦合, 封装 关注点分离
服务应该(获得该名称)完全独立,即:
在数据库级别共享数据的两个服务无法保证前者中的任何一个。
您“控制”这两项服务的事实完全无关紧要。今天你控制......明天你可能想要外包或替换其中一项服务。这应该就像确保适当的接口到位一样简单。
想象一下两个服务共享一个带有某个字段(varchar)的表。现在,一个服务需要将该字段更改为数字...其他服务停止运行 - 松耦合消失了。
大多数情况下,诀窍在于正确定义服务范围并明确规定服务的作用和不做的事情。您还应该避免将所有内容都变成服务。将您的服务粒度设置为高,服务将开始在任何地方突然出现,并且集成问题会升级。
话虽如此,在某些情况下,服务之间的数据集成会带来一些挑战。主要的前提应该是 - 数据只能属于一个服务。数据本质上与影响数据一致性和一致性的业务逻辑相关联,因此不应该有多个服务控制任何给定的数据。
答案 2 :(得分:2)
另一种方法是使某种数据源位于SOA服务之外。可以将此数据源视为数据缓存,操作数据源甚至数据仓库。提取包可以从服务中导出数据(和/或某种实时机制)。您可以按照自己的意愿查询此数据源。
这种方法的优点是可以维护SOA黑匣子,并且可以在知道如何将其耦合的情况下交换服务。
缺点是增加了复杂性和维护开销。
答案 3 :(得分:0)
SOA只是用于在Web服务背后部署组件的流行语。您拥有多少数据存储完全取决于您。在某些情况下,将分区数据放在单个组件后面是有意义的,在其他情况下,所有数据都存在于一个服务之后,而在其他情况下,许多公开服务接口的组件通过数据库的连接协议连接到同一个数据库。通过解决问题来解决问题,而不是强加人为约束。
答案 4 :(得分:0)
我认为SOA中没有任何原则,服务应该有单独的数据存储。一般来说,这实际上是不切实际的。是的,您可以拥有产品和订单服务,客户端可以使用您所说的Web服务调用进行连接,这在某些情况下可能是可以接受的。但是,如果您已经了解客户的行为和性能要求,那并不意味着您无法为客户提供特定服务。
我的意思是你应该有一个搜索服务,它返回在数据库中完成连接的订单和产品。这很实用,可以解决您的业务问题。
答案 5 :(得分:0)
令人遗憾的是,在“我可以使用共享数据库或不使用SOA”语句任务中,整个讨论正在恶化,这完全无关紧要,并且根本无法回答原始问题。
通常在现实世界中,数据已经存储在不同的系统中。例如,客户数据来自CRM,来自SAP的产品数据,来自另一个不同来源的合同数据。
这不是要求将这些数据技术整合在一起,而不是理解只有一个数据源。换句话说,企业中只有一个数据所有者,他们全权负责维护数据并确保正确的数据质量。
出于性能原因在本地存储数据意味着复制数据,这通常是一种危险的冒险,除非您有一个可靠的缓存策略。我认为Mosh在面对现有的应用程序环境时给出了一些明智的答案。