Backon:零依赖Python重试库,支持断路器与异步原生
速览
Backon是一个轻量级的Python重试库,具有零依赖性、原生异步支持和断路器模式。它旨在简化网络请求失败等场景下的重试逻辑,无需额外安装依赖即可集成。该工具可提升代码的健壮性和开发效率,适用于各类Python项目。
AI 深度解读
背景
在分布式系统、网络请求、API 调用等场景中,临时性故障(如网络抖动、服务过载、超时)是常态。开发者通常需要在代码中加入重试逻辑,以提高系统的健壮性。Python 社区已有 backoff 等库提供指数退避重试功能,但 backoff 库存在依赖较重、异步支持不够原生、缺乏断路器等功能局限。backon 应运而生,它定位为 backoff 的现代化演进,完全零依赖,同时原生支持异步(async/await),并集成了断路器、对冲请求(Hedging)、可组合的等待策略等高级特性。
核心内容
backon 是一个纯 Python 库(仅依赖标准库),用于为函数调用添加自动重试与退避逻辑。它提供四类 API:装饰器(@on_exception / @on_predicate)、函数式(retry())、上下文管理器(Retrying)、可调用对象(RetryingCaller / AsyncRetryingCaller),且同步与异步代码使用同一套 API。
安装与基本使用
pip install backon
要求 Python 3.10+。
装饰器示例:当函数抛出 ValueError 时,使用指数退避重试,最多 3 次。
import backon
@backon.on_exception(backon.expo, ValueError, max_tries=3)
def fetch_data():
return api.call()
基于返回值断言的重试:当函数返回 None 时,以固定间隔重试最多 5 次。
@backon.on_predicate(backon.constant, max_tries=5, interval=0.5)
def poll_status():
return check_ready()
函数式调用(同步或异步):
result = backon.retry(
fetch_data,
backon.expo,
exception=ValueError,
max_tries=3,
)
上下文管理器(同步与异步均支持):
with backon.Retrying(backon.expo, exception=ValueError, max_tries=3) as r:
result = r.call(fetch_data)
async with backon.Retrying(backon.constant, exception=ValueError, max_tries=3, interval=0.5) as r:
result = await r.async_call(fetch_data)
可调用对象(支持链式 .on() 绑定异常类型):
caller = backon.RetryingCaller(backon.expo, max_tries=3).on(ValueError)
result = caller(my_function, arg1, arg2)
异步版本:
caller = backon.AsyncRetryingCaller(backon.expo, max_tries=3).on(ValueError)
result = await caller(my_async_function, arg1, arg2)
等待策略(Wait Generators)
内置多种等待生成器:expo(指数退避)、constant(固定间隔)、fibonacci(斐波那契数列)、decay(衰减)、runtime(基于运行时)、randomized(随机)、incremental(递增),并支持通过 + 操作符组合。例如:wait_strategy = backon.expo(base=3) + backon.constant(interval=0.5)
停止条件(Stop Conditions)
使用 stop_after_attempt(按次数)、stop_after_delay(按总耗时)等,并通过 |(任意满足)或 &(全部满足)组合。例如:stop = stop_after_attempt(5) | stop_after_delay(30.0)
重试条件(Retry Conditions)
通过 retry_if_exception_type、retry_if_exception_message 等条件,并使用 retry_all / | / & 组合。例如:仅当异常类型为 HTTPError 且消息包含 "429" 时重试。
Jitter(抖动)
支持 full_jitter(全抖动)、随机抖动或无抖动。通过 jitter 参数传入。
回调函数(Handlers)
支持 on_attempt、on_backoff、on_success、on_giveup、before_sleep、before、after 等钩子,回调函数接收一个 details 字典,包含 tries(尝试次数)、elapsed(已用时间秒)、exception(异常)、value(返回值)、wait(下次等待时间)、start(开始时间)等信息。
全局开关
backon.disable() / backon.enable() 可全局禁用/启用重试,便于测试。也可通过 Retrying.enabled = False 对实例进行控制。
异步原生
所有装饰器、函数、上下文管理器均透明支持 async def 函数。无需额外适配。
自定义 Sleep
可通过 sleep 参数替换默认的 time.sleep,例如传入 lambda s: print(f"waiting {s}s") 或 backon.sleep_using_event(event) 用于测试中配合 asyncio.Event。
断路器(Circuit Breaker)
backon 内置断路器,状态机为 CLOSED(正常)→ OPEN(熔断)→ HALF_OPEN(半开试探恢复)。使用 BreakerRetrying 包装,可配置失败阈值、恢复超时、半开最大调用数。当断路器 OPEN 时调用会抛出 CircuitOpenError。
对冲请求(Hedging)
同时发起多个重试请求,第一个成功即返回。提供函数式 hedge()、装饰器 @on_hedge、上下文管理器 HedgingRetrying。
可选的指标收集(Prometheus / OpenTelemetry)
通过安装 prometheus_client 或 opentelemetry-api,可启用 PrometheusMetrics 或 OTelMetrics,收集重试次数、成功/失败次数、断路器状态切换、对冲请求数、每次重试耗时等指标。使用 set_metrics_collector() 注入。
测试工具模块
backon._testing 提供 disable_retries() / enable_retries()、limit_retries(n)、remove_backoff()(移除退避延迟)、assert_retried(func, expected_tries) / assert_not_retried 等上下文管理器与断言函数,方便编写测试。
Trio 支持
通过 backon._trio 模块提供 retry_exception 和 retry_predicate 装饰器,支持 trio 异步框架。
更多高级特性包括:
- 操作符重载:停止条件可用
|/&组合,等待生成器可用+组合。 - Iterator API:
for attempt in Retrying(...):可手动控制每次尝试。 - 现代化打包:PEP 621,PDM,py.typed 类型注解。
关键要点
- 零依赖:纯 Python,仅依赖标准库,安装极轻量。
- 四类 API:装饰器、函数式、上下文管理器、可调用对象,覆盖不同编程风格。
- 原生异步支持:同一套 API 无缝兼容同步与
async def,无需额外适配。 - 丰富的等待策略:指数退避、固定间隔、斐波那契、衰减、基于运行时、随机、递增,并支持
+组合。 - 灵活的条件组合:停止条件(次数/时间)与重试条件(异常类型/消息)可通过
|、&逻辑组合。 - 强大的回调系统:提供多种钩子(
on_attempt、on_backoff、on_success、on_giveup等)以监控重试过程。 - 断路器:内置三态断路器,自动熔断与
