微服务 A 依赖于微服务 B 和 C。当客户端调用服务 A 上的某个端点时,这将导致从 A 向服务 B 和 C 发出多个 HTTP 请求以获取相关详细信息。同时处理这种情况的最佳、性能有效的设计模式或方法是什么?
注意:在这种情况下我们没有使用 API 网关。
最佳答案
根据您的问题,我假设无法利用 event-based/reactive approach ,并且架构决策已经通过考虑权衡做出here (请注意,在此来源中,下面提出的方法被称为“混合”)。
编排
在这些条件下,您正在寻找的模式称为 Orchestration .查看this great answer更广泛的概述。
作为快速回顾,您可以使用类似 Spring Integration 的东西落实以下要点:
- 在处理对 A 的请求时,尽可能同时执行对 B 和 C 的调用,以实现 A 的最快响应时间
- 对并发调用的结果进行累加、转换和聚合,形成完整的响应实体
- 利用线程池限制对 B 和 C 的并发运行请求,以防止放大级联故障
- 快速失败:如果某些请求失败,则提前取消后续的一系列调用(即,如果对 B 的调用不成功,则不调用 C)
- 截止时间:涉及您可以等待当前正在运行的对 B 和 C 的一堆调用完成并在过去时由 A 响应错误的最大处理时间
更新 - 依赖 Reactor pattern 的实现在客户端
如果您可以使用 Spring 5/Spring Boot 2.x,您还可以使用 Spring WebFlux 以 react 方式调用 B 和 C。基于 Project Reactor实现以上几点。
从原理上讲,您可以执行以下操作:
@Service
public class MyService {
private final WebClient webClient;
...
public Mono<Details> someRestCall(String name) {
return this.webClient.get().url("{name}/details", name)
.retrieve().bodyToMono(ResponseEntity.class);
}
}
...
Mono<ResponseEntity> b1 = myService.someRestCall("serviceB");
Mono<ResponseEntity> c1 = myService.someRestCall("serviceC");
Mono<ResponseEntity> b2 = myService.someOtherRestCall("serviceB");
ResponseEntity response = Flux
.parallel(NUM_CPUS)
.merge(b1, c1, b2)
.limitRequest(MAX_REQUESTS)
.onErrorReturn(ERR_RESPONSE_ENTITY)
.blockLast(CUTOFF_TIMEOUT);
(基于 this example )
关于java - 从单个服务多次调用多个微服务的最佳方法或设计模式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51946603/