gabrielanhaia/laravel-circuit-breaker

基于 PHP 和 Laravel 框架开发的微服务电路断路器

1.0.0 2020-07-08 14:26 UTC

This package is auto-updated.

Last update: 2024-09-22 13:23:50 UTC


README

Build Status Code Coverage Licence Package Stars

Logo - Laravel Circuit Breaker

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。

在您决定使用哪种方法后,您可以调用三个方法

  1. 验证电路是否打开
if ($circuitBreaker->canPass($serviceName) !== true) {
    return;
}

您可以使用 canPass 函数以任何您想要的方式。当电路是 CLOSEDHALF_OPEN 时,它将始终返回 true。之后,您应该调用您的服务,并根据响应调用以下方法来更新电路控制变量。

  1. 如果成功
$circuitBreaker->succeed($serviceName);
  1. 如果失败
$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)。更多信息请参阅许可文件