tleckie/circuit-breaker

借助PHP中强大的Circuit Breaker库,您可以管理并保护应用程序免受停止工作的请求的影响,以避免过载。您需要进行的实现非常简单。

1.1.0 2021-05-21 05:56 UTC

This package is auto-updated.

Last update: 2024-09-23 18:18:04 UTC


README

使用强大的Circuit Breaker库,您将能够管理和保护应用程序免受停止工作的请求的影响,以避免过载。您需要进行的实现非常简单。

Scrutinizer Code Quality Build Status Code Intelligence Status

安装

您可以通过composer安装此包

composer require tleckie/circuit-breaker

在软件系统中,远程调用通常是指调用在不同进程(可能在网络上的不同机器上)运行的软件。与内存调用相比,远程调用的一个重大区别是它们可能会失败,或者在没有响应的情况下挂起,直到达到某些超时限制。更糟糕的是,如果您有多个调用者对一个无响应的供应商,那么您可能会耗尽关键资源,导致多个系统发生级联故障。在Michael Nygard的杰出著作《Release It》中,他将Circuit Breaker模式普及开来,以防止这种灾难性的级联。

Circuit Breaker背后的基本思想非常简单。您将受保护的函数调用包装在Circuit Breaker对象中,该对象监视故障。一旦故障达到某个阈值,Circuit Breaker就会跳闸,所有进一步的对Circuit Breaker的调用都将返回错误,而不会执行受保护的调用。通常,您还希望有一种监控警报,如果Circuit Breaker跳闸。

Circuit Breaker在微服务架构中被广泛使用,用于发现微服务调用之间的问题。主要思想是保护您的代码免受调用下线的微服务的无效调用。

功能

  • 自动更新。(即您不需要像其他库那样手动添加成功或失败方法)
  • 返回受保护函数的结果。
  • 重试超时。
  • 保护您的服务调用,如果它们被丢弃。

用法

  • 您必须使用三个参数创建CircuitBreaker类的实例。第一个必须是您首选的psr-16缓存实例,它必须实现Psr\SimpleCache\CacheInterface接口,并且不包括在此库中。
  • 第二个必需参数是库必须执行以进入开启状态的尝试次数。
  • 第三个参数是Circuit Breaker在向受保护服务发出新调用之前必须等待的秒数。
  • CircuitBreaker类提供了一个callService方法,您必须在其中实现闭包来调用服务。
  • 在闭包中,必须控制当服务不可操作时将触发的异常,该异常被捕获并创建一个CircuitBreakerException异常,通过其构造函数传递已处理的异常。
  • 此时,服务已经完全受到保护,不会失败。
  • 当CircuitBreaker进入开启状态时,即服务不可用,它将停止接收请求,在所有情况下抛出最后一个已知的异常,直到服务可用以接收新的请求。
  • 整个过程对您来说是透明和自动的。
  • 鉴于微服务架构的特性,建议使用所有前端和后端机器之间共享的集中式缓存存储。
<?php
require "vendor/autoload.php";

use Tleckie\CircuitBreaker\CircuitBreaker;
use Tleckie\CircuitBreaker\Exception\CircuitBreakerException;


$circuitBreaker = new CircuitBreaker(
    // Psr\SimpleCache\CacheInterface object, not included with this library.
    new SimpleCacheAdapter( ... ),
    3, // maxFailures
    60 // retryTimeout
);

// create your service instance
$service = new MyUserService( ... );

$serviceResponse = $circuitBreaker->callService(

    static function () use ($service) {
        try {

            return $service->users();

        } catch (ServiceTimeOutException $exception) {
            throw new CircuitBreakerException($exception);
        }

    },
    'my.user.service'
);