Пакет circuit-breaker від @algoyounes додає патерн circuit breaker у Laravel. Він відстежує збої для іменованого сервісу та запобігає каскадним відмовам, коли залежний сервіс недоступний:
- Відстеження стану у трьох режимах: closed, open і half-open
- Іменовані circuits, щоб ізолювати стан для кожного сервісу
- Колбеки життєвого циклу (наприклад,
onOpen,onSuccess) - Інтеграція з Guzzle через заголовок
X-Circuit-Key - І ще...
Колбеки зміни стану кола
Кожен сервіс має власне іменоване коло. Можна прив’язати колбеки, щоб реагувати на зміну стану кола або на успішні/неуспішні виклики:
$circuit = $this->circuitManager->forService('payment-service');
$circuit->onOpen(function (CircuitTransition $transition) {
Log::warning('Payment service circuit opened', [
'state' => $transition->getState(),
]);
});
$circuit->onSuccess(function (CircuitResult $result, CircuitTransition $transition) {
// Called when a wrapped call succeeds
});
$circuit->onFailure(function (CircuitResult $result, CircuitTransition $transition) {
// Called when a wrapped call fails
});
Кожен колбек спрацьовує на певну подію: наприклад, onOpen виконується, коли коло переходить у стан open (блокує виклики через помилки), а onSuccess — після успішного обгорнутого виклику. Ключ service-name ізолює стан для кожного сервісу, дозволяючи відстежувати залежності окремо.
Виконання операцій
Після налаштування кола обгорніть виклики сервісу в run(). Circuit breaker вирішить, дозволити, заблокувати або протестувати виклик залежно від поточного стану:
$circuit->run(function () {
return Http::post('https://payments.example.com/charge', $payload);
});
Також можна використати CircuitManager без створення екземпляра CircuitBuilder:
$this->circuitManager->run('payment-service', function () {
return Http::post('https://payments.example.com/charge', $payload);
});
Middleware для Guzzle
Якщо ваш проєкт використовує Guzzle напряму, пакет містить middleware, яке читає заголовок X-Circuit-Key, щоб визначити, яке коло застосувати:
use AlgoYounes\CircuitBreaker\Middleware\GuzzleMiddleware;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
$stack = HandlerStack::create();
$stack->push(GuzzleMiddleware::create());
$client = new Client(['handler' => $stack]);
$response = $client->get('https://api.example.com', [
'headers' => [
'X-Circuit-Key' => 'external-api',
],
]);
Дізнатися більше про пакет можна на GitHub: algoyounes/circuit-breaker.