Circuit Breaker (автоматический выключатель) — это паттерн проектирования, используемый в распределенных системах для повышения отказоустойчивости и предотвращения каскадных сбоев. Он помогает управлять ситуациями, когда внешние сервисы или ресурсы становятся недоступными или работают с ошибками. Давайте разберем, как работает Circuit Breaker и зачем он нужен.
В распределенных системах микросервисы часто взаимодействуют друг с другом. Если один из сервисов становится недоступным или начинает отвечать с ошибками, это может привести к каскадным сбоям. Например, если сервис A вызывает сервис B, а сервис B не отвечает, сервис A может зависнуть в ожидании ответа, что приведет к истощению ресурсов (например, потоков или памяти) и, в конечном итоге, к сбою сервиса A.
Circuit Breaker работает по аналогии с автоматическим выключателем в электрических цепях. Он отслеживает количество ошибок при вызове внешнего сервиса. Если количество ошибок превышает определенный порог, Circuit Breaker "разрывает цепь" и временно прекращает вызовы проблемного сервиса. Это позволяет системе "отдохнуть" и предотвращает дальнейшие сбои.
Spring Cloud предоставляет библиотеку Resilience4j, которая реализует паттерн Circuit Breaker. Давайте рассмотрим пример использования.
Для использования 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>
Circuit Breaker можно настроить в application.yml
.
resilience4j.circuitbreaker:
instances:
userService:
registerHealthIndicator: true
slidingWindowSize: 10
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
waitDurationInOpenState: 5s
failureRateThreshold: 50
Аннотация @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";
}
}
Метод отката (fallbackMethod
) вызывается, если Circuit Breaker находится в состоянии Open или если вызов завершился ошибкой. Это позволяет предоставить клиенту альтернативный ответ вместо ошибки.
Рассмотрим пример полной реализации 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 позволяет создавать более устойчивые и надежные микросервисные приложения.