gabrielanhaia / laravel-circuit-breaker
基于 PHP 和 Laravel 框架开发的微服务电路断路器
Requires
- gabrielanhaia/php-circuit-breaker: ^1.0
- illuminate/support: ^5.6|^6.0|^7.0|^8.0
This package is auto-updated.
Last update: 2024-09-22 13:23:50 UTC
README
Laravel Circuit Breaker 是基于 Michael T. Nygard 所著的《Release It!设计并部署可生产软件(实用程序员)》一书开发的。在这本书中,Michael 推广了电路断路器的概念。
当我们与微服务一起工作时,有时会遇到系统不可用的情况,这最终会在我们的应用程序中引起问题。为了防止我们这边出现任何问题,并确保服务不会被多次调用,我们应该使用电路断路器。
有关电路断路器的更多信息,请参阅 这里。
注意:此包是为 Laravel 开发的,如果您使用的是其他框架,我建议您查看以下存储库: Gabriel Anhaia 的 PHP Circuit Breaker
安装
您可以通过 Composer 安装此包
composer require gabrielanhaia/laravel-circuit-breaker
您可以使用以下方式发布
php artisan vendor:publish --provider="GabrielAnhaia\LaravelCircuitBreaker\Providers\CircuitBreakerServiceProvider"
这是发布配置文件的包含内容
return [ 'driver' => 'redis', 'exceptions_on' => false, 'time_window' => 20, 'time_out_open' => 30, 'time_out_half_open' => 20, 'total_failures' => 5 ];
用法
使用 CircuitBreaker 有两种方法。您可以直接使用对象 GabrielAnhaia\PhpCircuitBreaker\CircuitBreaker
。它可以由 DI(依赖注入)自动注入;不需要注册。
第二种方法是使用 GabrielAnhaia\LaravelCircuitBreaker\CircuitBreakerFacade
类在您的类中调用 Facade。
在您决定使用哪种方法后,您可以调用三个方法
- 验证电路是否打开
if ($circuitBreaker->canPass($serviceName) !== true) { return; }
您可以使用 canPass 函数以任何您想要的方式。当电路是 CLOSED 或 HALF_OPEN 时,它将始终返回 true。之后,您应该调用您的服务,并根据响应调用以下方法来更新电路控制变量。
- 如果成功
$circuitBreaker->succeed($serviceName);
- 如果失败
$circuitBreaker->failed($serviceName);
通过这三个简单的方法,您可以在执行时控制应用程序的流程。
设置
如果您想更改 config/circuit_breaker.php
中的默认设置,可以这样做。
$settings = [ 'exceptions_on' => false, // Define if exceptions will be thrown when the circuit is open. 'time_window' => 20, // Time window in which errors accumulate (Are being accounted for in total). 'time_out_open' => 30, // Time window that the circuit will be opened (If opened). 'time_out_half_open' => 20, // Time out that the circuit will be half-open. 'total_failures' => 5 // Number of failures necessary to open the circuit. ];
注意:不需要定义这些设置(它们是默认值);它们将自动定义。
更多信息
假设您正在使用以下设置
$settings = [ 'exceptions_on' => false, // Define if exceptions will be thrown when the circuit is open. 'time_window' => 20, // Time window in which errors accumulate (Are being accounted for in total). 'time_out_open' => 30, // Time window that the circuit will be opened (If opened). 'time_out_half_open' => 60, // Time out that the circuit will be half-open. 'total_failures' => 5 // Number of failures necessary to open the circuit. ];
您的其中一个服务是一个支付网关,由于某种原因,您尝试每隔 2 秒调用一次。第一次调用网关时,它以 200(HTTP 状态码)响应,然后您使用服务标识符调用方法 "succeed"(您可以为每个服务创建一个)。
在第二次、第三次、第四次、第五次和第六次调用中,网关不可用,所以您再次调用 "failed" 方法。
失败总数为 5,现在当您调用 "canPass" 方法时,它将返回 "false",服务将不再被调用。此时,电路已打开,它将保持 "OPEN" 状态 30 秒(time_out_open),然后它将在此时刻将状态更改为 "HALF_OPEN"。此时,您可以再次尝试调用服务,如果它失败,它将保持 "OPEN" 状态另外 30 秒。
如果前四次尝试失败,而第五次成功会发生什么?然后,计数器将被重置。
"time_window" 设置是用来做什么的?每次故障都会存储在Redis中,并有一个过期日期。如果第一次故障正好发生在12:00:10,并且"时间窗口"是从12:00:40后的30秒开始,这次故障将不会计入触发电路断开的故障总数。简而言之,要触发电路,必须在Y(时间窗口)秒内出现X(总故障数)。
安全
如果您发现任何与安全相关的问题,请通过电子邮件ga.contact.me@gmail.com联系,而不是使用问题跟踪器。
致谢
许可
MIT许可(MIT)。更多信息请参阅许可文件。