ilicmiljan / retry-master
RetryMaster 是一个灵活且可扩展的 PHP 库,用于处理操作重试。
Requires
- php: ^8.0
- psr/log: ^3.0
Requires (Dev)
- infection/infection: ^0.26.19
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2024-08-29 21:01:53 UTC
README
RetryMaster 是一个灵活且可扩展的 PHP 库,用于处理操作重试。它提供了一种简单、声明性的方式来管理可能因临时问题而失败的操作。通过使用 RetryMaster,您可以轻松实现具有可自定义策略的健壮重试逻辑,以确定何时以及如何执行重试。
功能
- 灵活的重试策略:从各种内置重试策略中选择,或创建自己的策略。您可以轻松控制基于异常类型和数量、超时、最大尝试次数等何时以及如何执行重试。
- 可配置的退避策略:使用包括固定延迟、指数退避或自定义退避逻辑在内的各种退避策略来控制重试之间的延迟。
- 详细的重试统计信息:收集并访问有关重试操作的详细统计信息,例如总尝试次数、成功尝试次数、失败尝试次数和总睡眠时间。
- 易于使用的重试模板:使用 RetryTemplate 来执行具有重试逻辑的操作。只需提供操作逻辑,RetryTemplate 就会处理其余部分。
- 自定义重试和恢复回调:定义在每次重试尝试和所有重试失败时执行的逻辑。
目录
安装
RetryMaster 可作为 Composer 包使用。您可以在终端运行以下命令将其添加到项目中
composer require ilicmiljan/retry-master
这将将 RetryMaster 添加到您项目的依赖项中,并将其下载到您的 vendor 目录。
安装后,您可以通过在 PHP 文件的顶部添加适当的 use
语句来使用 RetryMaster 类。例如
use IlicMiljan\RetryMaster\RetryTemplate; use IlicMiljan\RetryMaster\Policy\Retry\MaxAttemptsRetryPolicy; use IlicMiljan\RetryMaster\Policy\Backoff\ExponentialBackoffPolicy;
如果您使用的是自动执行此操作的框架,请确保运行 composer dump-autoload
。
使用方法
在您的 PHP 应用程序中使用 RetryMaster 涉及设置 RetryTemplate
并使用此模板执行操作。随着构建器和接口的引入,您可以使用 RetryTemplateBuilder
方便地创建 RetryTemplate
。您可以通过在构建 RetryTemplate 时指定重试和退避策略来自定义重试逻辑。
以下是一个基本示例
use IlicMiljan\RetryMaster\RetryTemplateBuilder; use IlicMiljan\RetryMaster\Callback\RetryCallback; use IlicMiljan\RetryMaster\Context\RetryContext; $retryTemplate = (new RetryTemplateBuilder())->build(); $retryCallback = new class implements RetryCallback { public function doWithRetry(RetryContext $context) { // Your operation goes here. For example: // return $this->repository->find($id); } }; $result = $retryTemplate->execute($retryCallback);
在此示例中,如果抛出异常,操作将重试最多三次(默认最大尝试次数)。在每次尝试之间,将有一个固定延迟一秒(默认退避策略)。
自定义重试逻辑
您可以使用构建器指定自定义重试和退避策略来创建 RetryTemplate
use IlicMiljan\RetryMaster\RetryTemplateBuilder; use IlicMiljan\RetryMaster\Policy\Retry\MaxAttemptsRetryPolicy; use IlicMiljan\RetryMaster\Policy\Backoff\UniformRandomBackoffPolicy; $retryPolicy = new MaxAttemptsRetryPolicy(5); $backoffPolicy = new UniformRandomBackoffPolicy(500, 1500); $retryTemplate = (new RetryTemplateBuilder()) ->setRetryPolicy($retryPolicy) ->setBackoffPolicy($backoffPolicy) ->build();
在此示例中,操作将重试最多五次,尝试之间的延迟将是介于 500 毫秒和 1500 毫秒之间的随机数字。
处理重试失败
您可以提供一个恢复回调来处理所有重试尝试失败的情况
use IlicMiljan\RetryMaster\RetryTemplateBuilder; use IlicMiljan\RetryMaster\Callback\RetryCallback; use IlicMiljan\RetryMaster\Callback\RecoveryCallback; use IlicMiljan\RetryMaster\Context\RetryContext; $retryTemplate = (new RetryTemplateBuilder())->build(); $retryCallback = new class implements RetryCallback { public function doWithRetry(RetryContext $context) { // Your operation goes here. } }; $recoveryCallback = new class implements RecoveryCallback { public function recover(RetryContext $context) { // Your recovery logic goes here. For example: // return $this->fallbackRepository->find($id); } }; $result = $retryTemplate->executeWithRecovery($retryCallback, $recoveryCallback);
收集重试统计信息
您可以从 RetryTemplate 获取有关重试操作的统计信息
$retryStatistics = $retryTemplate->getRetryStatistics(); echo 'Total attempts: ' . $retryStatistics->getTotalAttempts() . "\n"; echo 'Successful attempts: ' . $retryStatistics->getSuccessfulAttempts() . "\n"; echo 'Failed attempts: ' . $retryStatistics->getFailedAttempts() . "\n"; echo 'Total sleep time: ' . $retryStatistics->getTotalSleepTimeMilliseconds() . "ms\n";
有关更多使用示例,请参阅每个类中的内联注释。
文档
概述
RetryMaster 设计用于简化 PHP 应用程序中重试操作的实施。它提供了一套管理重试逻辑的工具,包括可自定义的重试和退避策略以及详细的重试统计信息。
重试策略
重试策略确定在失败后是否应该重试操作。RetryMaster 包含几个内置重试策略,例如
-
AlwaysRetryPolicy
:此策略总是允许重试,无论异常类型或迄今为止的尝试次数。它可以在需要无限期重试直到操作成功的情况中使用。然而,应该谨慎使用,因为它可能导致操作始终失败时出现无限循环。 -
CompositeRetryPolicy
:此策略将是否重试的决定委托给多个其他策略。它允许以乐观或悲观的方式组合多个策略。在乐观模式(默认模式)下,如果任何策略允许,则操作将重试。在悲观模式下,只有当所有策略都允许时,操作才会重试。 -
MaxAttemptsRetryPolicy
:此策略允许操作重试指定的最大次数。当您想限制操作的重试次数以避免过多的重试时,它很有用。 -
NeverRetryPolicy
:此策略禁止任何重试尝试,无论操作或其结果如何。当您不希望对某些操作执行任何重试,无论其是否失败时,它很有用。 -
NonRepeatingExceptionRetryPolicy
:此策略只有在最后一次失败尝试抛出的异常类型与当前异常类型不同的情况下才允许重试。在预期操作会因相同类型的异常而反复失败,并且重试不会改变结果的情况下,这很有益。 -
SimpleRetryPolicy
:此策略固定次数地重试失败的操作,并针对特定的一组异常。它可以配置最大尝试次数属性和重试异常列表。如果异常在重试异常列表中,或者列表为空,并且尚未达到最大尝试次数,则 shouldRetry 方法将返回 true。 -
SpecificExceptionRetryPolicy
:此策略根据发生的异常类型决定是否重试失败的操作。它初始化为特定的异常类,如果导致失败的异常是配置类的实例,则 shouldRetry 方法将返回 true。 -
TimeoutRetryPolicy
:此策略根据自第一次尝试以来的总经过时间来决定是否重试失败的操作。它初始化为以毫秒为单位的超时时间,如果自第一次尝试以来的经过时间小于配置的超时时间,则 shouldRetry 方法将返回 true。
您还可以通过实现 RetryPolicy
接口来创建自己的重试策略。
退避策略
回退策略确定重试尝试之间的延迟。RetryMaster 包含几个内置的回退策略,例如
-
ExponentialBackoffPolicy
:此策略提供指数回退,这意味着重试尝试之间的等待时间随着每次失败尝试呈指数增长。这是网络应用的常规错误处理策略,有助于在一系列失败中逐步减少系统负载。 -
ExponentialRandomBackoffPolicy
:此策略提供具有随机组件的指数回退。重试尝试之间的等待时间呈指数增长,一旦计算出计算间隔,则会在计算间隔和计算间隔乘以乘数定义的范围内添加一个额外的随机组件。然后,将回退时间限制在最大间隔内,以防止等待时间无限增长。这有助于防止许多应用程序实例同时重试,从而可能压倒系统或服务,这种情况称为“雷鸣般的人群问题”。 -
FixedBackoffPolicy
:此策略在重试尝试之间应用固定延迟。等待时间始终相同,不受尝试次数的影响。这在重试成功的可能性与尝试次数无关,并且不需要随着时间的推移增加延迟的情况下很有用。 -
NoBackoffPolicy
:此策略在重试尝试之间不应用延迟。重试在失败后立即发生。这在您希望在失败后立即重试操作且不需要延迟的情况下很有用。然而,由于连续重试尝试之间没有延迟,因此在使用时应谨慎,因为它可能导致在持续失败的情况下系统负载增加。 -
UniformRandomBackoffPolicy
:此策略在重试尝试之间应用随机延迟(在指定范围内)。等待时间是在最小和最大间隔之间均匀分布的随机数。这可以用来在重试之间引入随机延迟,以避免出现暴风骤雨问题。
您也可以通过实现BackoffPolicy
接口来创建自己的回退策略。
自定义随机实现
对于ExponentialRandomBackoffPolicy
、UniformRandomBackoffPolicy
和其他使用随机组件的策略,您可以通过创建一个实现Random
接口的类来指定自己的自定义随机生成逻辑。这提供了将随机行为适应您的应用程序或环境特定要求的灵活性。
use IlicMiljan\RetryMaster\Policy\Backoff\ExponentialRandomBackoffPolicy; use IlicMiljan\RetryMaster\Util\Random; $randomGenerator = // Your implementation of the Random interface here. $backoffPolicy = new ExponentialRandomBackoffPolicy(); $backoffPolicy->setRandom($randomGenerator);
RetryMaster中的回退策略设计考虑了灵活性,默认情况下它们使用库中提供的RandomGenerator
实现。
重试统计信息
RetryStatistics
接口允许您收集有关重试操作的信息,例如总尝试次数、成功尝试次数、失败尝试次数和总睡眠时间。您可以使用提供的InMemoryRetryStatistics
实现或创建自己的实现。
重试和恢复回调
您可以通过实现RetryCallback
和RecoveryCallback
接口分别定义在每个重试尝试上执行的逻辑以及所有重试失败时执行的逻辑。
RetryTemplate
RetryTemplate
类简化了执行具有重试逻辑的操作的过程。您提供操作逻辑,RetryTemplate将根据配置的重试和回退策略处理重试。
睡眠
RetryMaster中的Sleeper
接口是实现重试操作中延迟机制的有力工具。它提供了一个方法来暂停脚本执行指定数量的毫秒。在实现回退策略、模拟测试环境中的网络延迟或限制对第三方服务的请求时特别有用。
您可以通过在RetryTemplate
中提供自己的实现来替换默认的NanoSleeper
。
use IlicMiljan\RetryMaster\RetryTemplateBuilder; use IlicMiljan\RetryMaster\Util\Sleeper; $sleeper = // Your implementation of the Sleeper interface here. $retryTemplate = (new RetryTemplateBuilder()) ->setSleeper($sleeper) ->build();
通过在RetryTemplate
中自定义Sleeper
接口,您完全控制应用程序处理延迟和睡眠间隔的方式,从而允许精确有效地管理重试操作。
日志记录
RetryMaster提供了一个集成的日志系统,您可以用于监视和调试重试操作。它使用PSR-3 Logger接口,使其与大多数日志库兼容。
您可以通过向RetryTemplate提供记录器来设置日志记录。
use IlicMiljan\RetryMaster\RetryTemplateBuilder; use Psr\Log\LoggerInterface; $logger = // Your PSR-3 compatible logger here. $retryTemplate = (new RetryTemplateBuilder()) ->setLogger($logger) ->build();
许可
RetryMaster根据MIT许可证授权。这意味着您可以在任何副本的软件/源代码中包含原始版权和许可通知的情况下自由使用和修改代码。
致谢
RetryMaster由@IlicMiljan开发和维护。它是许多小时辛勤工作和奉献的成果,并非常感谢开源社区的贡献。
本库深受Spring Retry库的启发,Spring Retry是Java Spring框架的一部分。Spring Retry的设计原则和结构对RetryMaster的形成起到了关键作用。如果您熟悉Spring Retry,您会发现RetryMaster中有许多相似之处。
特别感谢Spring Retry库背后的团队,他们的出色工作为本项目奠定了基础。他们致力于创建强大而灵活的重试操作解决方案,这对本项目是一个重要的灵感来源。
最后,向所有RetryMaster的贡献者和用户表示衷心的感谢。您的反馈、错误报告和功能建议对改进这个库至关重要。如果您想贡献力量,请随时提交pull request。