简体   繁体   English

两个微服务之间的通信

[英]Communication between two microservices

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. bill-ms 应该访问产品列表。 I'm wondering how I can communicate between those two ms.我想知道如何在这两个 ms 之间进行通信。 I have three approaches in my mind:我脑子里有三个办法:

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

  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)我可以在 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?现在我知道瓶颈是什么:说有 3 个 bill-ms 实例,rabbitMQ 如何决定响应哪个实例? 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.或者我该怎么说ribbon“给我bill-ms的免费实例来订阅来自rabbitMQ的请求”以进行负载平衡。

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 HTTP communication based microservices using this blog .首先,我使用这个博客开始了基于HTTP通信的微服务。 This works fine, but the problem is, that you create dependendies between your services.这工作正常,但问题是,您在服务之间创建了依赖关系。 Service A needs to be aware of a service B and needs to call it directly (via service discovery etc of course).服务 A需要知道服务 B并需要直接调用它(当然通过服务发现等)。 This is what you generally are trying to avoid when developing microservices.这是您在开发微服务时通常要避免的。

Another approach that I've started with lately, is using a message bus .我最近开始使用的另一种方法是使用message bus It's actually the 3rd option that you touched in your question.这实际上是您在问题中提到的第三个选项。

I have a service A , which stores persons (just an example).我有一个服务 A ,它存储人员(只是一个例子)。 What the service does when it creates a new person is: It sends an event on a RabbitMQ bus: personCreatedEvent .该服务在创建一个新人时所做的是: 它在RabbitMQ总线上发送一个eventpersonCreatedEvent If there are any other services interested in events like this, they can subcribe to them.如果有任何其他服务对此类事件感兴趣,他们可以订阅它们。 These interested services keep the relevant information that they are interested in, in their own datastores.这些感兴趣的服务将他们感兴趣的相关信息保存在他们自己的数据存储中。

With this last approach, there is not really a dependency between your services, because they don't communicate with each other directly.使用最后一种方法,您的服务之间并没有真正的依赖关系,因为它们不直接相互通信。 Service A is not aware of service B , because B just sends events to RabbitMQ to 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, eg 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 相同的模式或数据存储机制。它仅以最适合该服务的方式存储相关信息。

Have you looked at http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/ Part 2: inter-service communication section.您是否看过http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/第 2 部分:服务间通信部分。 It walks you through a specific example of how it is achieved它会引导您完成一个具体的例子,说明它是如何实现的

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.让我尝试在这个场景中添加更多细节,以强调在 Product 和 Biiling 的上下文中什么可能或可能不符合事件的条件。 The Billing-MS would need to talk to Product-Ms only in case an Order is placed. Billing-MS 仅在下订单时才需要与 Product-M 交谈。 Placing an Order would mostly be for a separate MS let's say Order-MS.下订单主要是针对单独的 MS,比如说 Order-MS。 When an order is created or placed, it will contain information of Products as line items.创建或下订单时,它将包含产品信息作为行项目。

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. Queue 应该在 RabbitMQ 中实现为 Work-queue。 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.这样,Billing-MS 的多个实例可以订阅同一个队列,但它将由一个且只有一个 Worker 处理。 There is no role of RIBBON in registering a service as a Worker to RabbitMQ. RIBBON 在将服务注册为 Worker 到 RabbitMQ 方面没有任何作用。 Each instance registers to a Queue and RabbitMQ decides RoundRobin which instance of Billing Service gets to process this event.每个实例注册到一个队列,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).为 Billing-Ms 获取订单中产品的详细信息应该是通过 Ribbon 进行负载平衡的服务到服务调用(如果这是您使用的)。 Getting Product details is not really an event, placing an Order is, hence the difference.获取产品详细信息并不是真正的事件,下订单才是,因此有所不同。

Also, Gateway should be used for exposing your Edge services.此外,Gateway 应该用于公开您的 Edge 服务。 For Service-to-Service calls, it would not be ideal to hop via Gateway service.对于服务到服务调用,通过网关服务进行跳转并不理想。

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

you can use below solution : Microservice A (ie UAA-SERVICE), and Microservice B. Microservice B want to connect microservice A and call services with Feign client.您可以使用以下解决方案:微服务A(即UAA-SERVICE)和微服务B。微服务B想要连接微服务A并使用Feign客户端调用服务。

1)This code for Microservice B 1)微服务B的这段代码

@AuthorizedFeignClient(name = "UAA-SERVICE")

public interface UaaServiceClient {公共接口 UaaServiceClient {

@RequestMapping(method = RequestMethod.GET, path = "api/users")
public List<UserDTO> getUserList();

@RequestMapping(method = RequestMethod.PUT, path = "api/user-info")
public String updateUserInfo(@RequestBody UserDTO userDTO);

} }

UAA-SERVICE : find this name with running Application Instances with registry. UAA-SERVICE :通过运行带有注册表的应用程序实例找到此名称。

2) In Microservice B (application.yml) Increase feign client connection Time Out------> feign: client: config: default: 2)在微服务B(application.yml)中增加feign client connection Time Out------> feign:client:config:default:
connectTimeout: 10000 readTimeout: 50000 enter image description here Increase hystrix Thread time out--------> connectTimeout: 10000 readTimeout: 50000在此输入图片描述增加 hystrix 线程超时-------->

hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 60000 shareSecurityContext: true hystrix:命令:默认:执行:隔离:线程:timeoutInMilliseconds:60000 shareSecurityContext:true

enter image description here 3) add @EnableFeignClients in main @SpringBootApplication class.在此处输入图像描述3) 在主 @SpringBootApplication 类中添加 @EnableFeignClients。 -------> This solution is working fine for me. -------> 这个解决方案对我来说很好用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM