Java 两个微服务之间的通信

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36701111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:35:04  来源:igfitidea点击:

Communication between two microservices

javaspringspring-bootjhipstermicroservices

提问by SerhatTR

I am creating a project with microservices architecture. And I created two microservices.

我正在创建一个具有微服务架构的项目。我创建了两个微服务。

One of them is for product entity, the other is for bill entity. They have their own endpoints and they are connected together with the gateway (i am using jhipster microservices architecture).

其中一个用于产品实体,另一个用于票据实体。他们有自己的端点,并与网关连接在一起(我使用的是 jhipster 微服务架构)。

The bill-ms should access to list of products. I'm wondering how I can communicate between those two ms. I have three approaches in my mind:

bill-ms 应该访问产品列表。我想知道如何在这两个 ms 之间进行通信。我脑子里有三个办法:

  1. Send a request from bill-ms to queue - like rabbitMQ, to get these products with these ids from product-ms (I don't know what is bottleneck of this)

  2. Send a request to gateway for product service and get the product from there (I'm worried about the latency because of the data size between them and in this way I'm not touching the database directly so I always depend on the gateway)

  3. I can duplicate the repositories, services and entities in bill-ms (it's an ugly way, and I think it breaks the rule of ms-architecture and the maintenance is very difficult)

  1. 从 bill-ms 向队列发送请求 - 就像rabbitMQ,从 product-ms 获取这些带有这些 id 的产品(我不知道这是什么瓶颈)

  2. 向网关发送产品服务请求并从那里获取产品(由于它们之间的数据大小,我担心延迟,这样我不会直接接触数据库,所以我总是依赖于网关)

  3. 我可以在 bill-ms 中复制仓库、服务和实体(这是一种丑陋的方式,我认为它打破了 ms-architecture 的规则,维护非常困难)

If you have any other approaches, I appreciate you to share it with me.

如果您有任何其他方法,我很感激您与我分享。

Edit

编辑

  1. Now I know what the bottleneck is: say that there are 3 instance of bill-ms and how does rabbitMQ decide which instance to respond? or how should I say to ribbon "give me the free instance of bill-ms to subscribe to the request from rabbitMQ" for load balancing.
  1. 现在我知道瓶颈是什么:说有 3 个 bill-ms 实例,rabbitMQ 如何决定响应哪个实例?或者我该怎么说ribbon“给我bill-ms的免费实例来订阅来自rabbitMQ的请求”以进行负载平衡。

回答by Kaj

I'm not sure if what I am going to answer is thé right way. I'm still learning myself.. But I can tell you how I've implemented my microservices attempts..

我不确定我要回答的是否正确。我自己还在学习..但我可以告诉你我是如何实现我的微服务尝试的..

First, I started with HTTPcommunication based microservices using this blog. This works fine, but the problem is, that you create dependendiesbetween your services. Service Aneeds to be aware of a service Band needs to call it directly(via service discovery etc of course). This is what you generally are trying to avoid when developing microservices.

首先,我使用此博客HTTP基于通信的微服务开始。这工作正常,但问题是,您在服务之间创建了依赖关系。服务 A需要知道服务 B并需要直接调用它(当然通过服务发现等)。这是您在开发微服务时通常要避免的。

Another approach that I've started with lately, is using a message bus. It's actually the 3rd option that you touched in your question.

我最近开始使用的另一种方法是使用message bus. 这实际上是您在问题中提到的第三个选项。

I have a service A, which stores persons (just an example). What the service does when it creates a new person is: It sends an eventon a RabbitMQbus: personCreatedEvent. If there are any other services interested in events like this, they can subcribeto them. These interested services keep the relevant informationthat they are interested in, in their own datastores.

我有一个服务 A,它存储人员(只是一个例子)。该服务在创建一个新人时所做的是: 它eventRabbitMQ总线上发送一个:personCreatedEvent。如果有任何其他服务对此类事件感兴趣,他们可以订阅它们。这些感兴趣的服务将他们感兴趣的相关信息保存在他们自己的数据存储中。

With this last approach, there is not really a dependency between your services, because they don't communicate with each other directly. Service Ais not aware of service B, because B just sends events to RabbitMQto whichever service is interested to these events and vice versa.

使用最后一种方法,您的服务之间并没有真正的依赖关系,因为它们不直接相互通信。服务 A不知道服务 B,因为 B 只是将事件发送到RabbitMQ对这些事件感兴趣的服务,反之亦然。

Of course, you have duplications between datastores over the service. But this can be profitable as well, e.g. service B doesn't need to use the same schema or data store mechanism as service A. It only stores the relevant information in the way that is best for this service.

当然,您在服务上的数据存储之间存在重复。但这也可以是有利可图的,例如,服务 B 不需要使用与服务 A 相同的模式或数据存储机制。它仅以最适合该服务的方式存储相关信息。

回答by jvence

Have you looked at http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/Part 2: inter-service communication section. It walks you through a specific example of how it is achieved

您是否看过http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/第 2 部分:服务间通信部分。它会引导您完成一个具体的例子,说明它是如何实现的

回答by sg4j

Let me try and add some more details to this scenario to stress what may or may not qualify as an event in the context of Product and Biiling. The Billing-MS would need to talk to Product-Ms only in case an Order is placed. Placing an Order would mostly be for a separate MS let's say Order-MS. When an order is created or placed, it will contain information of Products as line items.

让我尝试在这个场景中添加更多细节,以强调在 Product 和 Biiling 的上下文中什么可能或可能不符合事件的条件。Billing-MS 仅在下订单时才需要与 Product-M 交谈。下订单主要是针对单独的 MS,比如说 Order-MS。创建或下订单时,它将包含产品信息作为行项目。

Creation of an Order can be considered as an event. When Order creation event occurs, it can be pushed to a Queue for the Billing service. Queue should be implemented as a Work-queue in RabbitMQ. This way, multiple instances of the Billing-MS can subscribe to the same Queue but it'll be processed by one and only one Worker. There is no role of RIBBON in registering a service as a Worker to RabbitMQ. Each instance registers to a Queue and RabbitMQ decides RoundRobin which instance of Billing Service gets to process this event.

订单的创建可以被视为一个事件。当订单创建事件发生时,它可以被推送到计费服务的队列中。Queue 应该在 RabbitMQ 中实现为 Work-queue。这样,Billing-MS 的多个实例可以订阅同一个队列,但它将由一个且只有一个 Worker 处理。RIBBON 在将服务注册为 Worker 到 RabbitMQ 方面没有任何作用。每个实例注册到一个队列,RabbitMQ 决定 RoundRobin 哪个计费服务实例可以处理这个事件。

Getting details of Products in an Order for the Billing-Ms should be a Service-to-Service call load balanced via Ribbon (if that's what you are using). Getting Product details is not really an event, placing an Order is, hence the difference.

为 Billing-Ms 获取订单中产品的详细信息应该是通过 Ribbon 进行负载平衡的服务到服务调用(如果这是您使用的)。获取产品详细信息并不是真正的事件,下订单才是,因此有所不同。

Also, Gateway should be used for exposing your Edge services. For Service-to-Service calls, it would not be ideal to hop via Gateway service.

此外,Gateway 应该用于公开您的 Edge 服务。对于服务到服务调用,通过网关服务进行跳转并不理想。

回答by freemanpolys

One option is sending a request to bill microservice using it's registred name on the eureka registry.

一种选择是使用微服务在 eureka 注册表上的注册名称发送请求以对微服务进行计费。