服务应该在微服务架构中直接相互通信吗?


10

我有许多构成Web应用程序的Web服务。客户端可以通过REST API调用访问这些服务。

这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?

客户端是否应该一个接一个地直接调用它们以获取在客户端上加载网页所需的数据?

还是我应该在服务之上设置另一层来处理来自客户端的请求,获取该请求的数据,然后将其发送回客户端?


如果事物完全脱钩,那么它们就是完全独立的产品。因此,用户必须登录Contoso登录,然后Contoso登录将显示“您现在已登录!” ...,然后他们转到Contoso敏感数据存储,在框上打上“是的,我已登录”的复选框。 “ ...然后将其中的数据复制粘贴到Contoso数据处理器中……
user253751'1

Answers:


16

如果您希望您的服务看起来像这张图片,那么可以: 在此处输入图片说明 这不是您无法做到的,但是在大多数情况下,它将带来严重的后果。通过REST进行的通信不会显着断开服务的耦合。当某些服务接口更改时,所有相关服务很可能必须更改并重新部署。同样,在重新部署服务时,您将必须放下所有从属服务,这对于高可用性标准而言并不是一个好的设计。

最后,您将拥有微服务应用程序,该应用程序比替代的单体应用程序要慢,但几乎所有相同的问题都存在!

我不得不不同意@Robert Harvey

但是,实际上,您的一个或多个微服务(也许全部)将与某些中央数据存储(如SQL数据库)进行通信。

集成数据库是著名的反模式

更好的解决方案是使用发布-订阅模式,以使服务之间的通信异步:

在此处输入图片说明

请看一下实现这种交流方法的CQRS / ES方法,格雷格·扬(Greg Young)和其他人提供了大量有关该主题的精美视频。只是谷歌搜索“ CQRS / ES”关键字。通过这种方法,每个服务将同时成为发布者和订阅者,从而使服务的耦合度大大降低。

这是有关微服务的一系列很好的文章,阐明了围绕该主题的争议。非常详细的说明,并附有精美的插图。


2
好吧,首先,除了Fowler之外,我什么地方都没有听说过“集成数据库”一词。不要仅仅因为一个人说了福音就把它当作福音。其次,您没有足够的信息来称呼我所说的“集成数据库”。第三,在与您链接的同一篇文章中,Fowler实际上在适当的情况下称这类数据库有用。我喜欢事件总线的想法,尽管除非提高效率,否则我不认为它与调用微服务的常规API有何不同。
罗伯特·哈维

谢谢罗伯特,我将福勒的文章链接起来,以更好地说明想法,而不是与权威争辩。您描述该方法的方式听起来很像集成数据库之一。如果不同-一点都不明显。关于正确的情况-我认为通过数据库集成微服务不是一个好主意,因为它将我们带回到单片架构。
IlliakaillI

1
当然:每个微服务都将与自己的独立数据库或同一数据库中与其他服务的表无关的表进行对话。这样,服务就永远不会通过数据库交换信息,这意味着您可以轻松地水平扩展,并且瓶颈也更少。并且由于它们不共享相同的表-应用程序某一部分中的更改将不太可能影响其他部分。
IlliakaillI

1
您不能绝对将其声明为绝对值。可能有两个服务在同一个数据库中需要相同的信息,它们只是偶尔需要它,以这种方式访问​​就没有扩展问题,无论如何这两个服务已经在出于其他目的访问数据库,因此要站起来一个服务总线或API端点只是为了做到这一点是荒谬的。
罗伯特·哈维

1
但是要实现商业价值,您需要合并数据-“向我展示所有以下污水系统的存储能力,这些系统在给定以下雷达降雨数据的情况下将没有足够的存储容量,并使用结果对这张市政地图进行着色”。如果将所有数据拆分为服务,则仅意味着您以后可以合并数据。如果您禁止服务相互通信,则只需强迫自己将所有数据移至某个客户端,然后将数据加入该客户端即可。您希望将数据耦合到某个地方,因为这最终将为应用程序带来价值。
RemcoGerlich

8

阅读Udi Dahan关于SOA的评论,您会得到很多很好的想法。

服务是特定业务功能的技术授权。任何数据或规则都只能由一个服务拥有。

这意味着即使服务正在发布和订阅彼此的事件,我们也始终知道每条数据和规则的权威性真理源是什么。

同样,从业务功能的角度来看服务时,我们看到的是,许多用户界面会显示属于不同功能的信息-产品的价格以及是否有库存。为了使我们遵守以上对服务的定义,这使我们理解这种用户界面实际上是一个混搭-每个服务都具有处理其特定数据的UI片段。

特别是关于UI构成,Mauro Servienti关于UI构成的文章是一个很好的起点。另请参见Udi的视频,可在此处获得

这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?

如果两个服务彼此交换消息,那么您将获得一些耦合。那里的主要答案是,它们耦合到另一个服务的API -服务承诺保证即使内部结构发生变化也保持稳定的合同。

除此之外,诸如服务发现之类的技术还可以减轻对特定服务提供商的依赖,并且消息代理可以使生产者和消费者脱钩(它们仍然需要彼此理解消息,以及如何与消息代理的API进行交互-这是没有魔术的)。


7

这取决于您所说的“直接”。

根据微服务架构,将微服务通过诸如REST之类的接口在您自己的服务器上,甚至在外部服务器上调用其他微服务,这完全没问题。

不好的是,一个微服务使用直接方法调用来调用另一个;这将使两个微服务成为同一个整体的一部分。


这不是很好,并且会带来不良后果。请参阅我的答案以获取更多详细信息。
IlliakaillI

@IlliakaillI我说的是“根据微服务架构”是可以的。我并不是在暗示微服务架构没有任何后果,或者没有任何可改进之处。这里的问题是“书上是否有X?” 正确的答案是给定X的正确定义,这是本书所提供的。
Mike Nakis

是否有一本“参考书”告诉您如何构建真正的“微服务体系结构”?如今,微服务已成为流行语,许多人撰写了有关如何在REST之上构建整体的书。只是看我回答中的第一个图,以这种方式构建系统是没有意义的。如果您出于某种奇怪的原因而这样做-您肯定做错了。您最好改用整体式。如果您盲目地参考一些书籍(从权威那里进行论证)来支持您的设计选择,那么这不是进行软件设计的正确方法。
IlliakaillI

5

这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?

耦合不是一个坏词。 每个应用程序已经具有一定程度的耦合。与您的微服务通信的应用程序已经与微服务耦合,否则它们将无法工作。

使用微服务的真正目的是松耦合。您可以通过使一个微服务通过其公共API或使用事件总线询问另一个微服务来实现这一目标。

实际上,您的一个或多个微服务(也许全部)将与一些中央数据存储(如SQL数据库)进行通信。根据您要实现目标的方式,您可能只是让一个微服务以某种方式更改数据库数据,而另一个微服务将查询该数据以获取更改。


3
“集成数据库”是著名的反模式,更多细节请参见我的答案。
IlliakaillI

2

似乎在一般地谈论SOA和体系结构时,人们会陷入语义和行话中。是什么使服务“微”化?归根结底,无论使用哪种“评分系统”,显然都是某些特征不会使服务成为“非微观”服务。最高法院的法官对in亵行为说了什么?“看到它我就会知道。”

我敢肯定,有人会说这是一个没有答案的方法,但是他们却没有抓住要点。微服务体系结构旨在避免几个问题,其中包括“紧密耦合”问题。因此,如果最终创建的微服务纠缠于彼此的太多细节,那么您就创建了紧密的耦合,无论是使用发布/订阅消息总线还是直接调用,它都会破坏您有能力从各个部分组成新的解决方案,重新配置各个部分而无需降低整个系统的能力等


1

客户端是否应该一个接一个地直接调用它们以获取在客户端上加载网页所需的数据?

这取决于; 但是,我建议向客户端提供直接可用的功能,并隐藏(封装)如何组装结果的详细信息(例如,通过多个微服务)。

如果客户端在组合单个微服务结果时涉及太多逻辑,则可能会无意间导致某些业务逻辑渗入客户端。它也可能向您的客户端暴露更多的内部体系结构,从而阻碍了以后对微服务的重构。

因此,这意味着对于微服务,有时有一个包装微服务会很有帮助,该包装微服务为客户端提供具有有用抽象的终结点,并对其他(也许现在是内部)微服务进行更高级别的协调。


(此外,与客户端的往返行程可能比从微服务到彼此的往返行程更昂贵。)


例如,如果您查看GraphQL的发展方向,您会发现客户端向端点发出直接相关的查询,该查询可能会或可能不会实现为micrservices的集合。由于微服务的架构隐藏在GraphQL后面,这使得该架构更易于重构,并且对客户端更友好。参见例如https://stackoverflow.com/a/38079681/471129


1

微服务的主要目的是使您的应用程序松耦合。因此,服务不能互相调用。否则,它将被束缚耦合。但是,如果我们有两个需要共享数据的服务该怎么办?答案是Message Broker。因此,从客户端获取数据的服务可以将数据共享给中央消息代理,然后服务必须使用该数据才能使用它,对其进行转换并将其放入自己的数据存储中。我建议使用Kafka,因为您可以使用Kafka Stream即时连接来自不同主题的数据。PS。更好地将微服务按功能分开。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.