Каков наилучший подход или шаблон проектирования для одновременного вызова нескольких микросервисов из одной службы?

Microservice A имеет зависимость от B & C Microservice. Когда клиент вызывает определенную конечную точку в сервисе A, это вызовет несколько запросов HTTP к службам B & C из A, чтобы получить зависимые детали. Какова была бы оптимальная, эффективная структура проекта или подход для одновременного решения этого сценария?

NB: В этом случае мы не используем шлюз API.

+2
21 авг. '18 в 10:24
источник поделиться
1 ответ

Основываясь на вашем вопросе, я полагаю, что нет возможности использовать основанный на события/реактивный подход, и архитектурное решение уже принято с учетом компромиссов, как здесь рассматривается (обратите внимание: в этом источнике предложенный ниже подход называется "гибридом").

оркестровка

В этих условиях образец, который вы ищете, называется Orchestration. Ознакомьтесь с этим замечательным ответом для более широкого обзора.

В качестве быстрого резюме вы можете использовать что-то вроде Spring Integration для реализации следующих ключевых моментов:

  • При обработке запроса на A, выполняйте вызовы в B & C одновременно, где это возможно, для достижения быстрого времени отклика от A
  • Накопление, преобразование и агрегирование результатов одновременных вызовов в полный объект ответа
  • Использовать пулы потоков для ограничения одновременных запросов на B и C для предотвращения усиления каскадных сбоев
  • Быстрая сбой: ранняя отмена последующего набора вызовов, если некоторые запросы не выполняются (т.е. Не называть C, если вызов B не был успешным)
  • Отключение: задействовать максимальное время обработки, которое вы можете дождаться завершения текущего набора вызовов в B & C и ответить с ошибкой A на истекшее время

Обновление - полагайтесь на реализацию шаблона Reactor на стороне клиента

Если вы можете использовать Spring 5/Spring Boot 2.x, вы также можете сделать призывы к B & C реактивным способом, используя Spring WebFlux на основе 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);

(на основе этого примера)

+1
21 авг. '18 в 11:52
источник

Посмотрите другие вопросы по меткам или Задайте вопрос