从单个服务多次调用多个微服务的最佳方法或设计模式是啥?

Posted

技术标签:

【中文标题】从单个服务多次调用多个微服务的最佳方法或设计模式是啥?【英文标题】:What is the best approach or design pattern to call multiple microservices several times from a single service?从单个服务多次调用多个微服务的最佳方法或设计模式是什么? 【发布时间】:2019-01-27 12:28:03 【问题描述】:

微服务 A 依赖于微服务 B 和 C。当客户端调用服务 A 上的某个端点时,这将导致从 A 向服务 B 和 C 发出多个 HTTP 请求以获取依赖的详细信息。同时处理这种情况的最佳、性能有效的设计模式或方法是什么?

注意:在这种情况下,我们没有使用 API 网关。

【问题讨论】:

你通常应该尝试独立开发微服务。如果这是不可能的,您可以使用发布/订阅机制来通知服务有关相关事件。这解决了微服务之间的依赖太多问题。如果这也不可能(您需要触发业务逻辑),请始终考虑 asnc 调用远程服务。 【参考方案1】:

根据您的问题,我假设没有能力利用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,您还可以在 Project Reactor 的基础上使用 Spring WebFlux 以反应方式调用 B & C 以实现上述几点。

从原理上讲,您可以执行以下操作:

@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)

【讨论】:

以上是关于从单个服务多次调用多个微服务的最佳方法或设计模式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 微服务如何实现编排? [关闭]

优化架构设计的 10 个微服务最佳实践

微服务可靠性设计

如何管理在开发(而非测试)环境中使用多个微服务并对其进行模拟?

为啥DDD是设计微服务的最佳实践

微服务设计指导-微服务各层间应该如何调用