stfn / php-circuit-breaker
这是在PHP中实现的断路器模式
v0.1.5
2024-01-27 12:41 UTC
Requires
- php: ^8.1
- ext-redis: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.21.1
- phpunit/phpunit: ^10.3.2
README
此包提供了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)。有关更多信息,请参阅许可证文件。