我有许多构成Web应用程序的Web服务。客户端可以通过REST API调用访问这些服务。
这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?
客户端是否应该一个接一个地直接调用它们以获取在客户端上加载网页所需的数据?
还是我应该在服务之上设置另一层来处理来自客户端的请求,获取该请求的数据,然后将其发送回客户端?
我有许多构成Web应用程序的Web服务。客户端可以通过REST API调用访问这些服务。
这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?
客户端是否应该一个接一个地直接调用它们以获取在客户端上加载网页所需的数据?
还是我应该在服务之上设置另一层来处理来自客户端的请求,获取该请求的数据,然后将其发送回客户端?
Answers:
如果您希望您的服务看起来像这张图片,那么可以: 这不是您无法做到的,但是在大多数情况下,它将带来严重的后果。通过REST进行的通信不会显着断开服务的耦合。当某些服务接口更改时,所有相关服务很可能必须更改并重新部署。同样,在重新部署服务时,您将必须放下所有从属服务,这对于高可用性标准而言并不是一个好的设计。
最后,您将拥有微服务应用程序,该应用程序比替代的单体应用程序要慢,但几乎所有相同的问题都存在!
我不得不不同意@Robert Harvey
但是,实际上,您的一个或多个微服务(也许全部)将与某些中央数据存储(如SQL数据库)进行通信。
集成数据库是著名的反模式
更好的解决方案是使用发布-订阅模式,以使服务之间的通信异步:
请看一下实现这种交流方法的CQRS / ES方法,格雷格·扬(Greg Young)和其他人提供了大量有关该主题的精美视频。只是谷歌搜索“ CQRS / ES”关键字。通过这种方法,每个服务将同时成为发布者和订阅者,从而使服务的耦合度大大降低。
这是有关微服务的一系列很好的文章,阐明了围绕该主题的争议。非常详细的说明,并附有精美的插图。
阅读Udi Dahan关于SOA的评论,您会得到很多很好的想法。
服务是特定业务功能的技术授权。任何数据或规则都只能由一个服务拥有。
这意味着即使服务正在发布和订阅彼此的事件,我们也始终知道每条数据和规则的权威性真理源是什么。
同样,从业务功能的角度来看服务时,我们看到的是,许多用户界面会显示属于不同功能的信息-产品的价格以及是否有库存。为了使我们遵守以上对服务的定义,这使我们理解这种用户界面实际上是一个混搭-每个服务都具有处理其特定数据的UI片段。
特别是关于UI构成,Mauro Servienti关于UI构成的文章是一个很好的起点。另请参见Udi的视频,可在此处获得。
这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?
如果两个服务彼此交换消息,那么您将获得一些耦合。那里的主要答案是,它们耦合到另一个服务的API -服务承诺保证即使内部结构发生变化也保持稳定的合同。
除此之外,诸如服务发现之类的技术还可以减轻对特定服务提供商的依赖,并且消息代理可以使生产者和消费者脱钩(它们仍然需要彼此理解消息,以及如何与消息代理的API进行交互-这是没有魔术的)。
这取决于您所说的“直接”。
根据微服务架构,将微服务通过诸如REST之类的接口在您自己的服务器上,甚至在外部服务器上调用其他微服务,这完全没问题。
不好的是,一个微服务使用直接方法调用来调用另一个;这将使两个微服务成为同一个整体的一部分。
这些服务应该能够彼此直接对话吗?如果是这样,这是否会使他们成为夫妇,这违背了微服务的概念?
耦合不是一个坏词。 每个应用程序已经具有一定程度的耦合。与您的微服务通信的应用程序已经与微服务耦合,否则它们将无法工作。
使用微服务的真正目的是松耦合。您可以通过使一个微服务通过其公共API或使用事件总线询问另一个微服务来实现这一目标。
实际上,您的一个或多个微服务(也许全部)将与一些中央数据存储(如SQL数据库)进行通信。根据您要实现目标的方式,您可能只是让一个微服务以某种方式更改数据库数据,而另一个微服务将查询该数据以获取更改。
客户端是否应该一个接一个地直接调用它们以获取在客户端上加载网页所需的数据?
这取决于; 但是,我建议向客户端提供直接可用的功能,并隐藏(封装)如何组装结果的详细信息(例如,通过多个微服务)。
如果客户端在组合单个微服务结果时涉及太多逻辑,则可能会无意间导致某些业务逻辑渗入客户端。它也可能向您的客户端暴露更多的内部体系结构,从而阻碍了以后对微服务的重构。
因此,这意味着对于微服务,有时有一个包装微服务会很有帮助,该包装微服务为客户端提供具有有用抽象的终结点,并对其他(也许现在是内部)微服务进行更高级别的协调。
(此外,与客户端的往返行程可能比从微服务到彼此的往返行程更昂贵。)
例如,如果您查看GraphQL的发展方向,您会发现客户端向端点发出直接相关的查询,该查询可能会或可能不会实现为micrservices的集合。由于微服务的架构隐藏在GraphQL后面,这使得该架构更易于重构,并且对客户端更友好。参见例如https://stackoverflow.com/a/38079681/471129。
微服务的主要目的是使您的应用程序松耦合。因此,服务不能互相调用。否则,它将被束缚耦合。但是,如果我们有两个需要共享数据的服务该怎么办?答案是Message Broker。因此,从客户端获取数据的服务可以将数据共享给中央消息代理,然后服务必须使用该数据才能使用它,对其进行转换并将其放入自己的数据存储中。我建议使用Kafka,因为您可以使用Kafka Stream即时连接来自不同主题的数据。PS。更好地将微服务按功能分开。