koschos/php-retry

PHP 重试库,是 Spring Retry 的移植版

v2.0.0 2018-12-23 13:58 UTC

This package is auto-updated.

Last update: 2024-09-05 15:30:56 UTC


README

Build Status

概述

PHP 重试库,这是一个 Spring Retry 的移植版 https://github.com/spring-projects/spring-retry

未移植

  • 注解支持
  • 有状态重试,重试状态,重试缓存
  • 重试上下文参数包
  • 重试监听器
  • 一些策略

安装

将包安装为 composer 依赖。

composer require koschos/php-retry

快速开始

示例

您只需要创建重试模板,这是您应该的重试配置。

// Build retry template with 5 retries and 100 milliseconds waits between them
$retryTemplate = RetryTemplateBuilder::getBuilder()
    ->withMaxAttempts(5)
    ->withBackOffPeriod(100)
    ->build();

// And run your code placed inside callback
$result = $retryTemplate->execute(new class implements RetryCallback {
  public function doWithRetry(RetryContext $context) {
      // dangerous code
  }
});

功能和 API

RetryTemplate

为了使处理更加健壮且不易失败,有时自动重试失败的操作(如果后续尝试可能成功)很有帮助。这类处理容易受到错误的影响。RetryOperations 接口的看起来是这样的

interface RetryOperations
{
    public function execute(RetryCallback $retryCallback);

    public function executeWithRecovery(RetryCallback $retryCallback, RecoveryCallback $recoveryCallback);
}

基本回调是一个简单的接口,允许您插入一些要重试的业务逻辑

interface RetryCallback
{
    public function doWithRetry(RetryContext $retryContext);
}

回调将被执行,如果它失败(通过抛出异常),它将被重试,直到成功或者实现决定终止。RetryOperations 接口中有两个处理回调和所有重试尝试耗尽时的恢复的方法。

RetryOperations 最简单的一般用途实现是 RetryTemplate。它可以这样使用

$template = new RetryTemplate();

// Retry policy with 30 seconds timeout
$policy = new TimeoutRetryPolicy();
$policy->setTimeout(30000);
$template->setRetryPolicy($policy);

$result = $template->execute($myRetryCallback);

在示例中,我们执行一个 Web 服务调用并将结果返回给用户。如果该调用失败,则重试直到达到超时。

RetryContext

RetryCallback 的方法参数是 RetryContext。许多回调将简单地忽略上下文,但在必要时可以使用它来存储迭代期间的数据。

RecoveryCallback

当重试耗尽时,RetryOperations 可以将控制权传递给另一个回调,即 RecoveryCallback。为了使用此功能,客户端必须实现 RecoveryCallback 接口并调用 executeWithRecovery 方法,例如

$template->executeWithRecovery($myRetryCallback, $myRecoveryCallback);

重试策略

在 RetryTemplate 中,执行方法中是否重试或失败的决定由 RetryPolicy 确定,RetryPolicy 也是 RetryContext 的工厂。RetryTemplate 负责使用当前策略创建 RetryContext 并在每次尝试时将其传递给 RetryCallback。在回调失败后,RetryTemplate 必须调用 RetryPolicy 以更新其状态(将存储在 RetryContext 中),然后询问策略是否可以尝试另一次。如果无法尝试另一次(例如,达到限制或检测到超时),则策略还负责识别耗尽状态,但不负责处理异常。如果没有可恢复的,RetryTemplate 将抛出原始异常。

interface RetryPolicy
{
    public function canRetry(RetryContext $context);

    public function open();

    public function close(RetryContext $context);

    public function registerException(RetryContext $context, \Exception $exception);
}

Retry 提供了一些简单的无状态 RetryPolicy 的一般用途实现,例如上面的示例中使用的 SimpleRetryPolicy 和 TimeoutRetryPolicy。

SimpleRetryPolicy 只允许在命名的异常类型列表中进行重试,直到达到固定的次数

$policy = new SimpleRetryPolicy(5, [\Exception.class, true]);

Retry 提供了以下重试策略

  • SimpleRetryPolicy
  • TimeoutRetryPolicy
  • AlwaysRetryPolicy
  • NeverRetryPolicy

退避策略

在尝试重试后遇到暂时性故障时,通常等待一会儿再尝试有助于解决问题,因为通常故障是由一些只能通过等待才能解决的问题引起的。如果 RetryCallback 失败,RetryTemplate 可以根据现有的 BackOffPolicy 暂停执行。

interface BackOffPolicy
{
    public function start(RetryContext $context);

    public function backOff(RetryContext $context);
}

重试提供了以下退避策略

  • 无退避策略
  • 固定退避策略