Мікросервіси залежать від кількох downstream-систем, що робить їх вразливими до відмов, таких як тайм-аути, повільні відповіді або недоступність сервісів. Resilience4j надає інструменти для їхнього елегантного оброблення, забезпечуючи надійність.
У цьому пості ми реалізуємо Resilience4j з Spring Boot 3.x, використовуючи WebClient для неблокуючих HTTP-запитів.
Опис проблеми
Розглянемо сервіс CurrencyService
, який отримує курси валют з зовнішнього API. Якщо API не відповідає або працює повільно, це може вплинути на весь сервіс. Наша мета — обробити такі помилки за допомогою Resilience4j з механізмами Circuit Breaker, Retry та Fallback.
Налаштування Gradle
Додайте наступні залежності до вашого build.gradle
:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.x.x'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
Налаштування
Оновіть application.yml
для конфігурації Resilience4j:
resilience4j:
circuitbreaker:
instances:
currencyService:
failure-rate-threshold: 50
wait-duration-in-open-state: 10s
permitted-number-of-calls-in-half-open-state: 2
sliding-window-size: 10
retry:
instances:
currencyService:
max-attempts: 3
wait-duration: 2s
timelimiter:
instances:
currencyService:
timeout-duration: 3s
Сервіс з WebClient
Ось як використовувати WebClient
з Resilience4j:
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.retry.annotation.Retry;
@Service
public class CurrencyService {
private final WebClient webClient;
public CurrencyService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://api.exchangerate-api.com/v4/latest").build();
}
@CircuitBreaker(name = "currencyService", fallbackMethod = "fallbackForCurrencyService")
@Retry(name = "currencyService")
public String getExchangeRates(String currency) {
return webClient.get()
.uri("/{currency}", currency)
.retrieve()
.bodyToMono(String.class)
.block();
}
public String fallbackForCurrencyService(String currency, Throwable throwable) {
return "Fallback response for " + currency + ": { 'USD': 1, 'EUR': 0.85 }";
}
}
Контролер
Експонуємо API для тестування сервісу:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CurrencyController {
private final CurrencyService currencyService;
public CurrencyController(CurrencyService currencyService) {
this.currencyService = currencyService;
}
@GetMapping("/api/rates/{currency}")
public String getExchangeRates(@PathVariable String currency) {
return currencyService.getExchangeRates(currency);
}
}
Потік запитів
https://github.com/codefarm0/SpringBoot
**Примітка — вихідний код для наведеної схеми — посилання
Моніторинг станів Circuit
- Увімкнення Actuator Додайте наступне до
application.yml
:
management:
endpoints:
web:
exposure:
include: health, metrics, resilience4j.circuitbreaker
- Моніторинг метрик Доступ до метрик circuit breaker через actuator на
/actuator/metrics/resilience4j.circuitbreaker
. - Детальніше Для отримання додаткових відомостей ви можете увімкнути інтеграцію Resilience4j з Prometheus або Micrometer для візуалізації за допомогою таких інструментів, як Grafana.
Імітація відмов
Змініть baseUrl
у CurrencyService
на неправильну URL-адресу.
Спостереження:
- Retry: Спроби отримати дані кілька разів.
- Circuit Breaker: Відстежує помилки та переходить у стан Open.
- Fallback: Повертає стандартну відповідь, коли circuit breaker's стан відкритий.
Висновок
Resilience4j забезпечує стійкість ваших мікросервісів за несприятливих умов. Поєднання Circuit Breaker, Retry та Fallback забезпечує надійний захист від помилок.
З Spring Boot 3.x та WebClient ви можете створювати неблокуючі, стійкі до помилок API, готові для сучасних розподілених архітектур. Бажаєте додаткову інформацію про інтеграцію з Prometheus чи вдосконалену конфігурацію?
— — — — —
Поділіться своїми думками та відгуками в розділі коментарів. Якщо ця стаття була корисною, поставте лайк і підписуйтеся на мене для отримання більше подібного контенту.
Перекладено з: Implementing Resilient Microservices with Resilience4j