hyperf/docs/en/circuit-breaker.md

3.5 KiB

Circuit Breaker

Installation

composer require hyperf/circuit-breaker

Why you need a Circuit Breaker ?

In distributed systems, it is often the case that the entire system is unavailable due to the unavailability of a basic service. This phenomenon is called the service avalanche effect. In response to service avalanches, a common practice is to downgrade services. The hyperf/circuit-breaker component is designed to solve this problem.

Usage

Why you need a Circuit Breaker ?

In distributed systems, it is often the case that the entire system is unavailable due to the unavailability of a basic service. This phenomenon is called the service avalanche effect. In response to service avalanches, a common practice is to downgrade services. The hyperf/circuit-breaker component is designed to solve this problem.

Using Circuit Breaker

The usage of the Circuit Breaker is very simple, just add the Hyperf\CircuitBreaker\Annotation\CircuitBreaker annotation, you can circuit break according to the specified strategy. For example, we need to query the user list in another service. The user list needs to be associated with a lots of tables. The query efficiency is low, but when the concurrent amount is normal, the corresponding speed is still reasonable. Once the amount of concurrency increases, it will slow down the response and cause the other service to slow down. At this time, we only need to configure the circuit break timeout period timeout to be 0.05 seconds, the failure count failCounter to be blown after more than 1 time, and the corresponding fallback is the searchFallback method of the App\UserService class. In this way, when the response times out and triggers the circuit break, it will not request the peer's service any more. Instead, it will directly downgrade the service from the current application, that is, return according to the method specified by fallback.

<?php
declare(strict_types=1);

namespace App\Services;

use App\UserServiceClient;
use Hyperf\CircuitBreaker\Annotation\CircuitBreaker;
use Hyperf\Di\Annotation\Inject;

class UserService
{
    /**
     * @Inject
     * @var UserServiceClient
     */
    private $client;

    /**
     * @CircuitBreaker(timeout=0.05, failCounter=1, successCounter=1, fallback="App\UserService::searchFallback")
     */
    public function search($offset, $limit)
    {
        return $this->client->users($offset, $limit);
    }

    public function searchFallback($offset, $limit)
    {
        return [];
    }
}

The default circuit break policy is Timeout Policy. If you want to implement the circuit break policy yourself, you only need to implement Handler inherited by Hyperf\CircuitBreaker\Handler\AbstractHandler.

<?php
declare(strict_types=1);

namespace Hyperf\CircuitBreaker\Handler;

use Hyperf\CircuitBreaker\Annotation\CircuitBreaker as Annotation;
use Hyperf\CircuitBreaker\CircuitBreaker;
use Hyperf\CircuitBreaker\Exception\TimeoutException;
use Hyperf\Di\Aop\ProceedingJoinPoint;

class DemoHandler extends AbstractHandler
{
    const DEFAULT_TIMEOUT = 5;

    protected function process(ProceedingJoinPoint $proceedingJoinPoint, CircuitBreaker $breaker, Annotation $annotation)
    {
        $result = $proceedingJoinPoint->process();

        if (is_break()) {
            throw new TimeoutException('timeout, use ' . $use . 's', $result);
        }

        return $result;
    }
}