Хотел бы задать вопрос о двух технологиях.

Сначала мы начали с приложения, которое должно вызывать остальные сторонние API, поэтому мы использовали Webflux WebClient в нашем проекте SpringBoot Webflux. Пока все хорошо, какое-то время у нас было успешное приложение.

Затем стороннее приложение (не наше) начало работать нестабильно, иногда не справляясь с нашими запросами. Нам пришлось реализовать какую-то логику повтора. После реализации логики повторных попыток, такой как WebClient reties, бизнес-поток теперь работает нормально. В основном мы брали логику напрямую из фреймворка. Например, в докладе @ simon-baslé, Cancel, Retry and Timeouts на недавнем SpringOne было дано много рабочих примеров.

.retryWhen(backoff(5, Duration.ofMillis(10).maxbackOff(Duration.ofSeconds(1)).jitter(0.4)).timeout(Duration.ofSeconds(5)

С другой стороны, в последнее время появляется все больше и больше приложений, приближающихся к шаблону Circuit Breaker. Проект Spring Cloud Circuit Breaker, поддерживаемый Resilience4J, является популярной реализацией с использованием Resilience4J для таких шаблонов, как Circuit Breaker, Bulkhead и, конечно же, Retry.

Следовательно, у меня возник вопрос, есть ли преимущество использования / комбинирования обоих с точки зрения повторных попыток?

Есть ли выгода от того, что они двое вместе? Есть недостатки?

Или достаточно одного из двух, в таком случае, какой, пожалуйста? И почему?

Спасибо

3
PatPatPat 24 Сен 2020 в 20:05

1 ответ

Лучший ответ

Мы (команда Resilience4j) реализовали пользовательские операторы Spring Reactor для CircuitBreaker, Retry и Timeout. Внутри Retry и Timeout используются операторы из Spring Reactor, но Resilience4j добавляет функциональность поверх него:

  1. Внешняя конфигурация Retry, Timeout и CircuitBreaker через файлы конфигурации
  2. Поддержка Spring Cloud Config для динамической настройки конфигурации
  3. Метрики, метрики, метрики;)

См. https://resilience4j.readme.io/docs/examples-1 и https://resilience4j.readme.io/docs/getting-started-3

Вы даже можете использовать аннотации, чтобы упростить задачу:

@CircuitBreaker(name = BACKEND)
@RateLimiter(name = BACKEND)
@Retry(name = BACKEND)
@TimeLimiter(name = BACKEND, fallbackMethod = "fallback")
public Mono<String> method(String param1) {
    return ...
}

private Mono<String> fallback(String param1, TimeoutException ex) {
    return ...;
}

Имейте в виду, что мы предоставляем собственный стартер Spring Boot. Я НЕ говорю о проекте Spring Cloud CircuitBreaker.

3
Robert Winkler 25 Сен 2020 в 06:35