Что такое Circuit Breaker и зачем он нужен?java-52

Circuit Breaker (автоматический выключатель) — это паттерн проектирования, используемый в распределенных системах для повышения отказоустойчивости и предотвращения каскадных сбоев. Он помогает управлять ситуациями, когда внешние сервисы или ресурсы становятся недоступными или работают с ошибками. Давайте разберем, как работает Circuit Breaker и зачем он нужен.

1. Проблема, которую решает Circuit Breaker

В распределенных системах микросервисы часто взаимодействуют друг с другом. Если один из сервисов становится недоступным или начинает отвечать с ошибками, это может привести к каскадным сбоям. Например, если сервис A вызывает сервис B, а сервис B не отвечает, сервис A может зависнуть в ожидании ответа, что приведет к истощению ресурсов (например, потоков или памяти) и, в конечном итоге, к сбою сервиса A.

2. Как работает Circuit Breaker?

Circuit Breaker работает по аналогии с автоматическим выключателем в электрических цепях. Он отслеживает количество ошибок при вызове внешнего сервиса. Если количество ошибок превышает определенный порог, Circuit Breaker "разрывает цепь" и временно прекращает вызовы проблемного сервиса. Это позволяет системе "отдохнуть" и предотвращает дальнейшие сбои.

2.1. Состояния Circuit Breaker

  • Closed (Закрыто): В этом состоянии Circuit Breaker пропускает все запросы к внешнему сервису. Если количество ошибок превышает порог, Circuit Breaker переходит в состояние Open.
  • Open (Открыто): В этом состоянии Circuit Breaker блокирует все запросы к внешнему сервису. Через некоторое время Circuit Breaker переходит в состояние Half-Open.
  • Half-Open (Полуоткрыто): В этом состоянии Circuit Breaker пропускает ограниченное количество запросов к внешнему сервису. Если эти запросы успешны, Circuit Breaker возвращается в состояние Closed. Если запросы завершаются ошибками, Circuit Breaker снова переходит в состояние Open.

3. Реализация Circuit Breaker в Spring

Spring Cloud предоставляет библиотеку Resilience4j, которая реализует паттерн Circuit Breaker. Давайте рассмотрим пример использования.

3.1. Добавление зависимостей

Для использования Circuit Breaker в Spring Boot необходимо добавить зависимость resilience4j-spring-boot2 в pom.xml.

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
    <version>1.7.1</version>
</dependency>

3.2. Настройка Circuit Breaker

Circuit Breaker можно настроить в application.yml.

resilience4j.circuitbreaker:
  instances:
    userService:
      registerHealthIndicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 5
      permittedNumberOfCallsInHalfOpenState: 3
      waitDurationInOpenState: 5s
      failureRateThreshold: 50

3.3. Использование Circuit Breaker

Аннотация @CircuitBreaker позволяет применить Circuit Breaker к методу.

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class UserService {

    private final RestTemplate restTemplate;

    public UserService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @CircuitBreaker(name = "userService", fallbackMethod = "fallbackGetUser")
    public String getUser(Long id) {
        return restTemplate.getForObject("http://user-service/users/" + id, String.class);
    }

    public String fallbackGetUser(Long id, Throwable t) {
        return "Fallback response: User service is unavailable";
    }
}

3.4. Fallback Method

Метод отката (fallbackMethod) вызывается, если Circuit Breaker находится в состоянии Open или если вызов завершился ошибкой. Это позволяет предоставить клиенту альтернативный ответ вместо ошибки.

4. Преимущества Circuit Breaker

  • Отказоустойчивость (Fault Tolerance): Circuit Breaker предотвращает каскадные сбои, временно блокируя вызовы проблемного сервиса.
  • Улучшение производительности (Improved Performance): Блокируя вызовы к недоступным сервисам, Circuit Breaker помогает избежать истощения ресурсов.
  • Автоматическое восстановление (Automatic Recovery): Circuit Breaker автоматически переходит в состояние Half-Open и проверяет, восстановился ли сервис.
  • Гибкость (Flexibility): Circuit Breaker можно настроить под конкретные требования, такие как порог ошибок, время ожидания и количество запросов в состоянии Half-Open.

5. Пример полной реализации

Рассмотрим пример полной реализации Circuit Breaker в Spring Boot.

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class UserService {

    private final RestTemplate restTemplate;

    public UserService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @CircuitBreaker(name = "userService", fallbackMethod = "fallbackGetUser")
    public String getUser(Long id) {
        return restTemplate.getForObject("http://user-service/users/" + id, String.class);
    }

    public String fallbackGetUser(Long id, Throwable t) {
        return "Fallback response: User service is unavailable";
    }
}
resilience4j.circuitbreaker:
  instances:
    userService:
      registerHealthIndicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 5
      permittedNumberOfCallsInHalfOpenState: 3
      waitDurationInOpenState: 5s
      failureRateThreshold: 50

Резюмируем

Circuit Breaker — это паттерн, который помогает управлять сбоями в распределенных системах, предотвращая каскадные сбои и улучшая отказоустойчивость. Он работает, отслеживая количество ошибок и временно блокируя вызовы к проблемным сервисам. В Spring Circuit Breaker можно реализовать с помощью библиотеки Resilience4j, которая предоставляет аннотации и гибкие настройки для управления состоянием вызовов. Использование Circuit Breaker позволяет создавать более устойчивые и надежные микросервисные приложения.