prestashop/circuit-breaker

PHP 的断路器实现

v4.0.1 2021-10-12 15:22 UTC

This package is auto-updated.

Last update: 2024-09-20 11:14:59 UTC


README

codecov PHPStan Psalm Build

主要原则

circuit breaker

此库与 PHP 7.2.5+ 兼容。

安装

composer require prestashop/circuit-breaker

使用

Symfony Http Client 和 Guzzle Client 实现

默认情况下,Circuit Breaker 使用 Symfony Http Client 库,所有客户端选项均可在 官方文档 中描述。

为了向后兼容,我们允许您使用 Guzzle Client 而不是 Symfony Http Client。要使用 Guzzle,您需要使用设置工厂的 setClient() 设置 Guzzle 客户端,如下例所示

use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\Client\GuzzleClient

$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$factorySettings = new FactorySettings(2, 0.1, 10);
$factorySettings->setClient(new GuzzleHttpClient());

$circuitBreaker = $circuitBreakerFactory->create($factorySettings);

请注意,客户端选项取决于您选择的客户端实现!

对于 Guzzle 实现,客户端选项在 HttpGuzzle 文档 中描述。

简单的断路器

您可以使用工厂创建一个简单的断路器。

默认情况下,您需要为断路器定义 3 个参数

  • the failures: 定义尝试访问服务的次数;
  • the timeout: 定义在认为服务不可达之前等待的时间;
  • the threshold: 定义在尝试再次访问服务之前等待的时间(一旦认为服务不可达);

当断路器打开(即“使用”时,如果服务不可达),将使用 fallback 回调。

您最好返回与您的远程调用预期的相同类型的响应。

use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;

$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$circuitBreaker = $circuitBreakerFactory->create(new FactorySettings(2, 0.1, 10));

$fallbackResponse = function () {
    return '{}';
};

$response = $circuitBreaker->call('https://api.domain.com', [], $fallbackResponse);

如果您未指定任何回退,默认情况下断路器将返回一个空字符串。

use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;

$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$circuitBreaker = $circuitBreakerFactory->create(new FactorySettings(2, 0.1, 10));
$response = $circuitBreaker->call('https://unreacheable.api.domain.com', []); // $response == ''

您还可以定义客户端选项(或者如果您愿意,甚至设置自己的客户端)。

use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;

$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$settings = new FactorySettings(2, 0.1, 10);
$settings->setClientOptions(['method' => 'POST']);
$circuitBreaker = $circuitBreakerFactory->create($settings);
$response = $circuitBreaker->call('https://api.domain.com/create/user', ['body' => ['firstname' => 'John', 'lastname' => 'Doe']]);

高级断路器

如果您需要更多控制您的断路器,您应该使用 AdvancedCircuitBreaker,它管理更多功能

  • the stripped failures: 定义当断路器处于半开状态时尝试访问服务的次数(当它尝试在不可达后到达服务时);
  • the stripped timeout: 定义在再次认为服务不可达之前等待的时间(在半开状态下);
  • the storage: 用于存储断路器状态和转换。默认情况下是 SimpleArray,因此如果您想“缓存”您的服务不可达的事实,您应该使用持久化存储;
  • the transition dispatcher: 如果您需要订阅转换事件(例如:基于 Symfony EventDispatcher 的分发器可用),则使用

存储

use Doctrine\Common\Cache\FilesystemCache;
use PrestaShop\CircuitBreaker\AdvancedCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\Storage\DoctrineCache;

$circuitBreakerFactory = new AdvancedCircuitBreakerFactory();
$settings = new FactorySettings(2, 0.1, 60); //60 seconds threshold

//Once the circuit breaker is open, the fallback response will be returned instantly during the next 60 seconds
//Since the state is persisted even other requests/processes will be aware that the circuit breaker is open
$doctrineCache = new FilesystemCache(_PS_CACHE_DIR_ . '/addons_category');
$storage = new DoctrineCache($doctrineCache);
$settings->setStorage($storage);

$circuitBreaker = $circuitBreakerFactory->create($settings);
$response = $circuitBreaker->call('https://unreachable.api.domain.com/create/user', []);

测试

composer test

代码质量

composer cs-fix && composer phpcb && composer psalm && composer phpcs

我们在 CI 管理中的贡献期间也使用 PHPQA 来检查代码质量。

如果您想使用它(使用 Docker)

docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa --report --ignoredDirs vendor,tests

如果您想使用它(使用 Composer)

composer global require edgedesign/phpqa=v1.20.0 --update-no-dev
phpqa --report --ignoredDirs vendor,tests