两个微服务之间的通信

时间:2016-04-18 17:58:51

标签: java spring spring-boot jhipster microservices

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

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

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

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

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

  3. 我可以用bill-ms复制存储库,服务和实体(这是一种丑陋的方式,我认为它打破了ms架构的规则并且维护非常困难)

  4. 如果您有任何其他方法,我感谢您与我分享。

    修改

    1. 现在我知道瓶颈是什么:说有3个bill-ms实例,rabbitMQ如何决定响应哪个实例?或者我该如何对Ribbon" 给我一个bill-ms的免费实例来订阅来自rabbitMQ的请求"用于负载平衡。

5 个答案:

答案 0 :(得分:33)

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

首先,我开始使用基于HTTP通信的微服务using this blog。这很好,但问题是,您在服务之间创建了 dependendies 服务A 需要了解服务B ,并且需要直接将其称为 (当然,通过服务发现等)。这是您在开发微服务时通常要避免的。

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

我有一个服务A ,它存储人员(仅举例)。该服务在创建新人时的作用是:它在event总线上发送RabbitMQpersonCreatedEvent。 如果有任何其他服务对此类事件感兴趣,他们可以订阅给他们。这些感兴趣的服务会在他们自己的数据存储中保留他们感兴趣的相关信息

使用最后一种方法,您的服务之间并不存在依赖关系,因为它们不会直接相互通信。 服务A 不了解服务B ,因为B只会向RabbitMQ发送事件给任何对这些事件感兴趣的服务,反之亦然。

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

答案 1 :(得分:2)

您是否看过http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/第2部分:服务间通信部分。它将向您介绍如何实现它的具体示例

答案 2 :(得分:0)

让我尝试在此场景中添加更多细节,以强调在产品和Biiling环境中可能有或没有资格作为事件。只有在下订单时,Billing-MS才需要与Product-Ms交谈。下订单主要是针对一个单独的MS,比如订单-MS。创建或下达订单时,它将包含产品的信息作为行项目。

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

获取Billing-Ms订单中产品的详细信息应该是通过功能区平衡的服务到服务呼叫负载(如果这是您正在使用的)。获取产品详细信息并不是真正的事件,因此订购顺序是不同的。

此外,Gateway应该用于公开您的Edge服务。对于服务到服务呼叫,通过网关服务跳转是不理想的。

答案 3 :(得分:0)

一种选择是使用eureka注册表中的注册名称发送请求以向微服务收费。

答案 4 :(得分:0)

您可以使用以下解决方案: 微服务 A(即 UAA-SERVICE)和微服务 B。 微服务 B 想要连接微服务 A 并使用 Feign 客户端调用服务。

1)微服务B的这段代码

@AuthorizedFeignClient(name = "UAA-SERVICE")

公共接口 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 :通过注册表运行应用程序实例找到此名称。

2) 在微服务 B (application.yml) 增加假客户端连接超时时间------> 假装: 客户: 配置: 默认:
连接超时:10000 读取超时:50000 enter image description here 增加 hystrix 线程超时-------->

hystrix: 命令: 默认: 执行: 隔离: 线: timeoutInMilliseconds: 60000 shareSecurityContext: 真

enter image description here 3) 在@SpringBootApplication 主类中添加@EnableFeignClients。-------> 这个解决方案对我来说效果很好。