用 Python 实现的、具有指数退避(exponential backoff)策略的重试装饰器

以下是一个使用 Python 实现的、具有指数退避(exponential backoff)策略的重试装饰器的完整示例:

import time
import functools
import random

def exponential_backoff_retry(max_retries=3, base_delay=1, max_delay=None, jitter=True):
    """
    一个具有指数退避策略的重试装饰器。

    参数:
        max_retries (int): 最大重试次数,默认为3次。
        base_delay (float): 初始延迟时间(秒),默认为1秒。
        max_delay (float): 最大延迟时间(秒),默认为None(无限制)。
        jitter (bool): 是否添加随机扰动,默认为True。
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            retry_count = 0
            while retry_count < max_retries:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    retry_count += 1
                    if retry_count >= max_retries:
                        raise e  # 超过最大重试次数,抛出异常

                    # 计算等待时间
                    delay = base_delay * (2 ** (retry_count - 1))
                    if jitter:
                        delay *= random.uniform(0.5, 1.5)  # 添加随机扰动
                    if max_delay is not None:
                        delay = min(delay, max_delay)  # 限制最大延迟时间

                    print(f"Function {func.__name__} failed with error: {str(e)}")
                    print(f"Retrying... (attempt {retry_count}/{max_retries})")
                    print(f"Waiting for {delay:.2f} seconds before next retry.")
                    time.sleep(delay)
            return None  # 如果所有重试都失败,返回None
        return wrapper
    return decorator

# 使用示例
@exponential_backoff_retry(max_retries=5, base_delay=2, max_delay=30, jitter=True)
def unreliable_function():
    """一个可能会失败的函数"""
    import random
    if random.random() < 0.7:  # 70%的概率模拟失败
        raise Exception("Operation failed!")
    return "Success!"

# 测试
result = unreliable_function()
print(f"Final result: {result}")

参数说明

  • max_retries: 最大重试次数,默认为3次。
  • base_delay: 初始延迟时间(秒),默认为1秒。
  • max_delay: 最大延迟时间(秒),默认为None(无限制)。
  • jitter: 是否添加随机扰动,默认为True

工作原理

  1. 装饰器结构: 使用 Python 的装饰器模式,exponential_backoff_retry 是一个返回装饰器的高阶函数。
  2. 重试逻辑: 在 wrapper 函数中实现重试逻辑,每次调用目标函数时捕获异常。
  3. 指数退避计算: 每次重试时,根据公式 delay = base_delay * 2^(retry_count - 1) 计算等待时间。
  4. 随机扰动: 如果启用了 jitter,会在计算的延迟时间基础上乘以一个随机因子(0.5到1.5之间),以避免多个客户端同时重试导致的冲突。
  5. 最大延迟限制: 如果设置了 max_delay,确保延迟时间不会超过该值。

使用方法

将装饰器应用到需要重试的函数上:

@exponential_backoff_retry(max_retries=5, base_delay=2)
def your_function():
    # 可能会失败的操作
    pass

示例输出

当函数失败时,装饰器会按照指数退避策略进行重试,输出类似以下内容:

Function unreliable_function failed with error: Operation failed!
Retrying... (attempt 1/5)
Waiting for 1.23 seconds before next retry.
Function unreliable_function failed with error: Operation failed!
Retrying... (attempt 2/5)
Waiting for 3.45 seconds before next retry.
...

这个装饰器在处理可能会失败的操作(如网络请求、外部服务调用等)时非常有用,通过指数退避策略可以有效减少对目标服务的压力并提高操作的成功率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值