Где может помочь circuit breaker



Представим, есть сервис агрегатор, который собирает данные с других сервисов. Если внешний сервис не доступен, мы не хотим долго ждать, а хотим дать ответ пользователю с тем, что есть



Здесь может помочь circuit breaker (CB)



Запрос из сервиса X в сервис Y обвязывается в CB, который работает так:



У CB есть три состояния:



1. Closed — с внешним сервисом все ок, запросы идут как обычно

2. Open — внешний сервис не доступен, не делаем запросы, сразу возвращаем ошибку

3. Half open — "flapping" состояние. Пока не знаем доступен ли сервис, проверяем его



И переходы между состояниями:



Изначально в Closed



Closed -> Open: внешний сервис стал недоступен. Например, по кол-ву ошибок либо по времени ответа

Open -> Half open: прошло некоторое время, пока висим в Open. Начинаем по-тихоньку проверять внешний сервис

Half open -> Open: проверили, внешний сервис еще мертв

Half open -> Closed: проверили, внешний сервис жив



---



Почему бы просто не использовать паттерн timeout, где запрос отваливается, если не отработал за некоторый таймаут? Можно. При этом используя CB мы также оказываем услугу внешнему сервису — мы не начинаем в него неистово ретраить, если знаем, что он скорее всего недоступен. Поэтому если у вас микросервисная архитектура, и все межсервисные походы обвязаны в CB, то это может помочь предотвратить каскадные падения