-
-
Notifications
You must be signed in to change notification settings - Fork 27
feat: 添加多种Backoff重试策略实现 #1036
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 添加多种Backoff重试策略实现 #1036
Conversation
- 新增BackoffInterface接口定义 - 实现FixedBackoff: 固定延迟策略 - 实现LinearBackoff: 线性增长延迟策略 - 实现ExponentialBackoff: 指数增长延迟策略(支持抖动) - 实现FibonacciBackoff: 斐波那契序列延迟策略 - 实现DecorrelatedJitterBackoff: 去相关抖动延迟策略 - 实现PoissonBackoff: 泊松分布随机延迟策略 所有策略统一使用毫秒作为时间单位,支持延迟上限设置, 适用于不同场景的重试需求。
This comment was marked as spam.
This comment was marked as spam.
- 新增BackoffTestCase抽象基类,包含通用测试方法 - 新增FixedBackoffTest:测试固定延迟策略 - 新增LinearBackoffTest:测试线性增长延迟策略 - 新增ExponentialBackoffTest:测试指数增长延迟策略 - 新增FibonacciBackoffTest:测试斐波那契序列延迟策略 - 新增DecorrelatedJitterBackoffTest:测试去相关抖动延迟策略 - 新增PoissonBackoffTest:测试泊松分布随机延迟策略 所有测试类覆盖: - 接口实现验证 - 参数配置测试 - 延迟计算正确性 - 延迟上限限制 - 重置功能 - 边界条件测试 - 私有属性访问验证
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (5)
src/support/src/Backoff/FibonacciBackoff.php (1)
41-44: 建议:考虑添加初始延迟参数以提高灵活性。当前实现中,斐波那契数列从 1ms 开始(序列为 1, 1, 2, 3, 5, 8...),这与其他策略(如
FixedBackoff默认 500ms,ExponentialBackoff默认 100ms)相比显得较小。建议考虑添加一个乘数或基础延迟参数,以便用户能够调整初始延迟范围。- public function __construct(int $max = 10000) + public function __construct(int $base = 100, int $max = 10000) { + $this->base = $base; $this->max = $max; }然后在
next()中使用$delay = $this->curr * $this->base;src/support/src/Backoff/PoissonBackoff.php (1)
16-16: 建议:将中文注释改为英文以保持代码一致性。其他 Backoff 类使用英文注释,建议保持一致。
- private int $mean; // 平均延迟 + private int $mean; // Mean delay (milliseconds)src/support/src/Backoff/FixedBackoff.php (1)
14-20: 建议:类描述过于具体。类注释提到 "email retry mechanism",但这是一个通用的 Backoff 策略实现。建议将描述改为更通用的表述。
/** - * Fixed backoff implementation for email retry mechanism. + * Fixed backoff implementation. * * This class provides a simple backoff strategy where the delay between * retry attempts remains constant (fixed). It's useful when you want * predictable retry intervals regardless of how many attempts have been made. */src/support/src/Backoff/DecorrelatedJitterBackoff.php (2)
14-14: 建议添加类级别的文档块。与
LinearBackoff相比,此类缺少描述去相关抖动算法的类级别文档块。建议添加以保持一致性并解释 AWS 最佳实践的实现细节。+/** + * Decorrelated jitter backoff strategy implementation. + * + * This class implements the decorrelated jitter algorithm based on AWS best practices. + * The delay is randomized between the base value and the previous delay multiplied + * by a factor, which helps spread out retry attempts across distributed systems. + * + * @see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ + */ class DecorrelatedJitterBackoff implements BackoffInterface
90-96: 文档注释与实际行为不一致。注释标注为 "1-based attempt index",但
$attempt初始值为 0,行为与LinearBackoff(标注为 "0-based")完全相同。建议统一文档描述以避免混淆。/** - * 1-based attempt index. + * Get the current attempt number. + * + * @return int The current attempt number (0-based, incremented after each next() call) */ public function getAttempt(): int
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/support/src/Backoff/BackoffInterface.php(1 hunks)src/support/src/Backoff/DecorrelatedJitterBackoff.php(1 hunks)src/support/src/Backoff/ExponentialBackoff.php(1 hunks)src/support/src/Backoff/FibonacciBackoff.php(1 hunks)src/support/src/Backoff/FixedBackoff.php(1 hunks)src/support/src/Backoff/LinearBackoff.php(1 hunks)src/support/src/Backoff/PoissonBackoff.php(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/*/src/**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All components use the namespace pattern:
FriendsOfHyperf\{ComponentName}
Files:
src/support/src/Backoff/BackoffInterface.phpsrc/support/src/Backoff/LinearBackoff.phpsrc/support/src/Backoff/DecorrelatedJitterBackoff.phpsrc/support/src/Backoff/PoissonBackoff.phpsrc/support/src/Backoff/ExponentialBackoff.phpsrc/support/src/Backoff/FibonacciBackoff.phpsrc/support/src/Backoff/FixedBackoff.php
**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.php: Follow PSR-12 coding standards for all PHP code
Use PHP-CS-Fixer for code formatting as configured in.php-cs-fixer.php
Use PHPStan for static analysis as configured inphpstan.neon.dist
Files:
src/support/src/Backoff/BackoffInterface.phpsrc/support/src/Backoff/LinearBackoff.phpsrc/support/src/Backoff/DecorrelatedJitterBackoff.phpsrc/support/src/Backoff/PoissonBackoff.phpsrc/support/src/Backoff/ExponentialBackoff.phpsrc/support/src/Backoff/FibonacciBackoff.phpsrc/support/src/Backoff/FixedBackoff.php
🧬 Code graph analysis (7)
src/support/src/Backoff/BackoffInterface.php (6)
src/support/src/Backoff/DecorrelatedJitterBackoff.php (3)
next(62-79)reset(84-88)getAttempt(93-96)src/support/src/Backoff/ExponentialBackoff.php (3)
next(73-94)reset(99-102)getAttempt(107-110)src/support/src/Backoff/FibonacciBackoff.php (3)
next(49-63)reset(68-73)getAttempt(78-81)src/support/src/Backoff/FixedBackoff.php (3)
next(54-58)reset(68-71)getAttempt(82-85)src/support/src/Backoff/LinearBackoff.php (3)
next(71-85)reset(93-96)getAttempt(106-109)src/support/src/Backoff/PoissonBackoff.php (3)
next(28-48)reset(50-53)getAttempt(55-58)
src/support/src/Backoff/LinearBackoff.php (2)
src/support/src/Backoff/FixedBackoff.php (3)
next(54-58)reset(68-71)getAttempt(82-85)src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
src/support/src/Backoff/DecorrelatedJitterBackoff.php (2)
src/support/src/Backoff/FixedBackoff.php (4)
__construct(40-43)next(54-58)reset(68-71)getAttempt(82-85)src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
src/support/src/Backoff/PoissonBackoff.php (1)
src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
src/support/src/Backoff/ExponentialBackoff.php (1)
src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
src/support/src/Backoff/FibonacciBackoff.php (3)
src/support/src/Backoff/FixedBackoff.php (4)
__construct(40-43)next(54-58)reset(68-71)getAttempt(82-85)src/support/src/Backoff/LinearBackoff.php (4)
__construct(52-57)next(71-85)reset(93-96)getAttempt(106-109)src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
src/support/src/Backoff/FixedBackoff.php (1)
src/support/src/Backoff/BackoffInterface.php (3)
next(16-16)reset(18-18)getAttempt(20-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Seer Code Review
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Agent
🔇 Additional comments (9)
src/support/src/Backoff/BackoffInterface.php (1)
14-21: 接口设计简洁清晰!接口定义了三个核心方法,符合单一职责原则。所有具体的 Backoff 策略实现都遵循此接口规范,便于多态使用和策略切换。
src/support/src/Backoff/FibonacciBackoff.php (1)
49-63: 斐波那契逻辑实现正确!使用数组解构进行状态更新的写法简洁且正确,避免了临时变量的使用。延迟上限限制也正确实现。
src/support/src/Backoff/FixedBackoff.php (1)
40-58: 实现简洁正确!固定延迟策略的实现清晰明了,文档注释完整,符合接口规范。
src/support/src/Backoff/ExponentialBackoff.php (1)
73-94: 指数退避与抖动实现正确!使用
random_int()实现抖动是安全的做法(密码学安全的随机数生成器),有效防止了重试风暴(thundering herd)问题。先应用上限再添加抖动的顺序也是正确的。src/support/src/Backoff/LinearBackoff.php (4)
1-23: LGTM!命名空间遵循
FriendsOfHyperf\{ComponentName}模式,类文档块清晰地描述了线性退避算法的公式和行为。
25-57: LGTM!属性定义清晰,构造函数默认参数合理。
71-85: LGTM!线性延迟计算逻辑正确,先使用当前 attempt 计算延迟,再递增计数器,确保首次调用返回
initial值。
93-109: LGTM!
reset()和getAttempt()方法实现符合BackoffInterface接口规范,与FixedBackoff保持一致。src/support/src/Backoff/DecorrelatedJitterBackoff.php (1)
84-88: LGTM!
reset()方法正确重置了attempt和prevDelay两个状态属性,确保退避策略可以从头开始。
- 修复DecorrelatedJitterBackoffTest中的预期值问题 - 为非确定性策略(使用随机数的策略)添加isDeterministic()方法 - 修正测试用例以正确处理随机延迟范围 - 所有94个测试用例现在都能正常通过
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- 添加max()函数确保upper bound不小于base,避免random_int()参数错误 - 修复类声明缺少开大括号的语法错误 - 增加factor < 1.0和factor = 0的边界测试用例 - 所有97个Backoff测试用例现在都能正常通过
- 修复Knuth算法在mean > 700时exp(-mean)下溢为0的问题 - 根据均值大小使用不同算法: * mean <= 30: 使用原始Knuth算法 * 30 < mean <= 700: 使用正态分布近似 * mean > 700: 使用Box-Muller变换的截断正态分布 - 确保延迟值不为负数 - 更新默认均值为100,更适合典型延迟场景 - 添加大均值测试用例验证修复效果 - 所有99个测试用例全部通过
huangdijia
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
代码审查报告
变更总结
本 PR 为 friendsofhyperf/components 添加了完整的 Backoff(退避)重试策略实现,包括:
- BackoffInterface 统一接口
- 6种退避策略实现
- 完整的单元测试覆盖
潜在风险
高风险
- PoissonBackoff 数值稳定性
- 虽已修复数值下溢问题,但极端边界情况下仍需关注
中风险
-
静态变量状态污染
- PoissonBackoff 使用静态变量可能影响长时间运行的应用
-
性能考虑
- gaussRandom() 方法的三角函数计算开销
优化建议
- 使用实例变量替代静态变量
- 添加参数验证和异常处理
- 统一边界值处理策略
合规性
- ✅ 符合 PSR-12 编码规范
- ✅ 命名约定符合项目标准
- ✅ 测试覆盖率优秀(99个测试用例)
⚠️ 建议:统一使用英文注释
总体评价
高质量的代码实现,设计合理,测试完整。建议在合并前处理注释一致性问题。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 11 comments.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 10 comments.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: 添加多种Backoff重试策略实现 - 新增BackoffInterface接口定义 - 实现FixedBackoff: 固定延迟策略 - 实现LinearBackoff: 线性增长延迟策略 - 实现ExponentialBackoff: 指数增长延迟策略(支持抖动) - 实现FibonacciBackoff: 斐波那契序列延迟策略 - 实现DecorrelatedJitterBackoff: 去相关抖动延迟策略 - 实现PoissonBackoff: 泊松分布随机延迟策略 所有策略统一使用毫秒作为时间单位,支持延迟上限设置, 适用于不同场景的重试需求。 * test: 添加Backoff策略的单元测试 - 新增BackoffTestCase抽象基类,包含通用测试方法 - 新增FixedBackoffTest:测试固定延迟策略 - 新增LinearBackoffTest:测试线性增长延迟策略 - 新增ExponentialBackoffTest:测试指数增长延迟策略 - 新增FibonacciBackoffTest:测试斐波那契序列延迟策略 - 新增DecorrelatedJitterBackoffTest:测试去相关抖动延迟策略 - 新增PoissonBackoffTest:测试泊松分布随机延迟策略 所有测试类覆盖: - 接口实现验证 - 参数配置测试 - 延迟计算正确性 - 延迟上限限制 - 重置功能 - 边界条件测试 - 私有属性访问验证 * fix: 修复Backoff策略单元测试中的随机性问题 - 修复DecorrelatedJitterBackoffTest中的预期值问题 - 为非确定性策略(使用随机数的策略)添加isDeterministic()方法 - 修正测试用例以正确处理随机延迟范围 - 所有94个测试用例现在都能正常通过 * feat: 更新BackoffInterface接口文档,增加方法注释以提高可读性 * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat: 更新PoissonBackoff和测试用例,优化文档注释和代码格式 * fix: 修复DecorrelatedJitterBackoff中factor < 1.0时random_int()异常问题 - 添加max()函数确保upper bound不小于base,避免random_int()参数错误 - 修复类声明缺少开大括号的语法错误 - 增加factor < 1.0和factor = 0的边界测试用例 - 所有97个Backoff测试用例现在都能正常通过 * fix: 修复PoissonBackoff中大均值导致的数值下溢和无限循环问题 - 修复Knuth算法在mean > 700时exp(-mean)下溢为0的问题 - 根据均值大小使用不同算法: * mean <= 30: 使用原始Knuth算法 * 30 < mean <= 700: 使用正态分布近似 * mean > 700: 使用Box-Muller变换的截断正态分布 - 确保延迟值不为负数 - 更新默认均值为100,更适合典型延迟场景 - 添加大均值测试用例验证修复效果 - 所有99个测试用例全部通过 * fix: 优化PoissonBackoff中的延迟返回逻辑,确保返回值不为负数 * feat: 更新PoissonBackoff类中的注释,确保代码可读性和一致性 * feat: 重构后退策略类,统一继承自AbstractBackoff,优化参数验证和延迟计算逻辑 * feat: 优化AbstractBackoff和LinearBackoff类,移除未使用的变量,提升代码整洁性 * feat: 更新PoissonBackoff类中的参数注释,增强代码可读性 * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat: 更新后退策略构造函数参数类型为正整数,增强参数验证 * feat: 添加sleep方法到后退策略接口,提供延迟等待功能并返回延迟时间 * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: 移除多余的空行,优化代码可读性 --------- Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Summary
Features
Test Coverage
测试包括:
Test plan
Summary by CodeRabbit
发布说明
新功能
测试
✏️ Tip: You can customize this high-level summary in your review settings.