stfn/php-circuit-breaker

这是在PHP中实现的断路器模式

v0.1.5 2024-01-27 12:41 UTC

This package is not auto-updated.

Last update: 2024-09-21 15:40:55 UTC


README

Latest Version on Packagist

此包提供了PHP中断路器模式的实现。更多关于它的信息可以在这里找到。

安装

您可以通过composer安装此包

composer require stfn/php-circuit-breaker

用法

使用断路器包装您可能出错的函数,并且它将监控和处理故障。

use Stfn\CircuitBreaker\CircuitBreaker;

$result = CircuitBreaker::for('3rd-party-service')->call(function () {
    // Your function that could fail
});

状态

断路器可以有4种不同的状态。

关闭

关闭状态下,断路器完全运行,允许调用第三方服务。在此状态下发生的任何异常都将被计数。

半开

半开状态是一个过渡阶段,断路器允许调用第三方服务的一定数量的调用。如果这些调用成功,电路将再次关闭。然而,如果服务继续出现问题,电路将回到打开状态。

打开

打开状态表示断路器检测到关键故障,调用方法将立即失败,抛出CircuitOpenException异常。

强制打开

强制打开不是常规流程的一部分。当需要故意暂停调用服务时,可以将其用于此。在此状态下,将抛出CircuitOpenException异常。

要强制将断路器置于强制打开状态,请使用以下方法

use Stfn\CircuitBreaker\CircuitBreaker;

$breaker = CircuitBreaker::for('3rd-party-service')->forceOpenCircuit();

此功能提供了手动覆盖以暂时停止调用服务,在需要时提供额外的控制。

存储

默认情况下,断路器使用InMemoryStorage作为存储驱动程序,这对于大多数PHP应用程序来说并不合适。

更实用的做法是使用RedisStorage

use Stfn\CircuitBreaker\Storage\RedisStorage;
use Stfn\CircuitBreaker\CircuitBreaker;

$redis = new \Redis();
$redis->connect("127.0.0.1");

$storage = new RedisStorage($redis);

$result = CircuitBreaker::for('3rd-party-service')
    ->storage($storage)
    ->call(function () {
        // Your function that could fail
    });

您也可以编写自己的存储实现。您只需要实现CircuitBreakerStorage接口。

配置

每个断路器都有默认的配置设置,但您可以根据需要自定义它们

use Stfn\CircuitBreaker\CircuitBreaker;

$breaker = CircuitBreaker::for('3rd-party-service')
    ->withOptions([
        'failure_threshold' => 10, // Number of failures triggering the transition to the open state
        'recovery_time' => 120, // Time in seconds to keep the circuit breaker open before attempting recovery
        'sample_duration' => 60, // Duration in seconds within which failures are counted
        'consecutive_success' => 3 // Number of consecutive successful calls required to transition from half open to closed state
    ]);

排除某些故障

通过配置排除某些类型的故障以更改断路器的行为

use Stfn\CircuitBreaker\CircuitBreaker;

$breaker = CircuitBreaker::for('3rd-party-service')
    ->skipFailureCount(function ($exception) {
        return $exception->getCode() < 500;
    });

监听器

您可以通过扩展CircuitBreakerListener类来为断路器动作添加监听器

use Stfn\CircuitBreaker\CircuitBreakerListener;
use Stfn\CircuitBreaker\CircuitState;

class LoggerListener extends CircuitBreakerListener
{
    public function beforeCall(CircuitBreaker $breaker, \Closure $action,...$args) : void
    {
        Log::info("before call");    
    }
    
    public function onSuccess(CircuitBreaker $breaker, $result): void
    {
        Log::info($result);
    }

    public function onFail(CircuitBreaker $breaker, $exception) : void
    {
        Log::info($exception);
    }
    
    public function onStateChange(CircuitBreaker $breaker, CircuitState $previousState, CircuitState $newState)
    {
        Log::info($previousState, $newState);
    }
}

将监听器附加到断路器

use Stfn\CircuitBreaker\CircuitBreaker;

$breaker = CircuitBreaker::for('3rd-party-service')
    ->listeners([new LoggerListener()]);

测试

composer test

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件