Spring 微服务之间建立通信的不同方式
如果您正在使用涉及多个微服务的 Spring Boot 项目,您可能会觉得需要从微服务 m1 到微服务 m2 进行通信。根据业务用例,此通信可以是同步或异步类型。在进一步挖掘之前。让我们先了解用例。有两个微服务:
- 餐厅服务:负责维护餐厅服务的物品,处理订单等。
- 用户服务:负责维护用户详细信息。
现在假设用户访问了一家餐馆的页面,选择了一些他喜欢的菜肴并点击了“Place Order”按钮。当此请求到达餐厅服务时,该服务将希望在处理此订单之前验证用户详细信息。但是我们的用户详细信息位于用户服务下。因此,需要从餐厅服务到用户服务进行通信。从 m1 同步通信 m2 就像直接从 m1 调用 m2 的 API。
同步方式
当我们谈论同步通信时,可能有两种方式:
- REST 模板
- 假装
REST 模板
REST 模板是建立从 m1 到 m2 的同步通信的最简单方法。 RestTemplate 是 spring.framework.web.client 下的一个类,它充当同步客户端来执行 HTTP 请求。在下面的示例中,我们使用了 getForEntity 方法,该方法接受我们要调用的用户服务的完整 URL,后跟该 URL 应该返回的 Data-Object 类名,以及一个映射。如果提供的 userId 无效,API 调用将引发我们在餐厅服务端处理的自定义异常。
Java
HashMap params = new HashMap<>();
params.put("userId", orderDetails.getUserId());
try {
ResponseEntity response
= new RestTemplate().getForEntity(
"http://localhost:8080/users/{userId}",
User.class, params);
}
catch (Exception ex) {
throw new InvalidUserIdException(
"User Id " + orderDetails.getUserId()
+ " Not Found");
}
假装
如果您想采用这种方式,Feign 需要对这两个服务进行额外的配置。此方法使用标准Java接口。使用 feign over rest-template 的额外好处是您无需在此处对 URL 进行硬编码。 Eureka Client ID 也可用于服务器发现目的,以建立通信。
异步方式
建立通信的一种可能的异步方式是使用消息代理。让我们先了解用例。
考虑到上面讨论的微服务,假设用户已经下订单。现在订单将进入各个阶段,例如Accepted、Preparation-Started、Ready-To-Pick、Delivered 。假设订单的所有阶段都将由餐厅服务更新,我们希望在每次更新订单状态时通知用户服务。现在这可以通过任何一种方式实现,但异步方式在这里会更方便。
- Message-Broker:它充当 m1 和 m2 之间的中介服务。当 m1 必须与 m2 通信时,m1 会将消息推送给 broker,而不是直接发送给 m2。根据代理的类型(ActiveMQ 和 Kafka 是两个流行的消息代理,但它们有不同的通信方式),消息将被传送到 m2 的侦听器并采取相应的操作。这里 m1 将被称为生产者,而 m2 将被称为消费者。