Python异常重试模式教程_稳定系统设计

异常重试模式是在遇到网络超时、数据库连接中断等临时性错误时自动重试,以提升系统容错性;适用于可恢复错误,不适用于400/401等永久性错误,需保障幂等性、防雪崩、加强日志监控。

什么是异常重试模式

异常重试模式是在代码执行遇到临时性错误(比如网络超时、数据库连接中断、API限流)时,不立即失败,而是自动重复尝试几次,直到成功或达到最大重试次数。它不是掩盖bug,而是提升系统对瞬时故障的容忍度,让程序更健壮。

什么时候该用重试,什么时候不该用

适合重试的情况:HTTP请求超时、数据库连接短暂拒绝、第三方服务返回 503/429、文件锁暂时不可用等可恢复的临时错误。

不适合重试的情况:400/401/404 等客户端错误、数据校验失败、逻辑异常(如除零、KeyError)、磁盘满、权限不足等永久性问题——重试只会浪费资源,还可能引发重复操作(比如重复扣款)。

用装饰器实现简单重试逻辑

下面是一个轻量、可控的重试装饰器示例,支持自定义重试次数、延迟和异常类型:

import time
import functools

def retry(max_attempts=3, delay=1, backoff=2, exceptions=(Exception,)): def decorator(func): @functools.wraps(func) def wrapper(*args, *kwargs): current_delay = delay for attempt in range(max_attempts): try: return func(args, *kwargs) except exceptions as e: if attempt == max_attempts - 1: raise e time.sleep(current_delay) current_delay = backoff return None return wrapper return decorator

使用示例

@retry(max_attempts=3, delay=0.5, exceptions=(ConnectionError, TimeoutError)) def fetch_data(url): import requests return requests.get(url, timeout=2).json()

生产环境要注意的关键细节

实际部署中,仅加个装饰器远远不够,还需注意:

  • 幂等性必须保障:重试前确认操作是否可重复执行。例如调用支付接口,要带唯一请求ID并由服务端做去重;写数据库建议先查再插,或用 upsert。
  • 避免雪崩式重试:多个实例同时失败后立刻重试,可能压垮下游。可加入随机抖动(jitter),比如 time.sleep(current_delay * (0.5 + random.random()))
  • 记录与可观测性:每次重试应打日志(含尝试次数、异常类型、耗时),接入监控告警,便于判断是否是上游服务不稳定还是本端配置不合理。
  • 不要在事务内盲目重试:数据库事务中重试可能造成锁等待甚至死锁。更稳妥的做法是捕获异常后回滚,再在外层重试整个业务流程。