重试策略与超时控制
---
章节:进阶篇第6章
难度:⭐⭐⭐ 进阶级
阅读时间:25-30 分钟
核心收获:掌握重试策略的设计和超时控制的最佳实践
10.1 理论要点:重试的艺术
10.1.1 重试的分类
| 分类 | 说明 | 示例 |
|---|---|---|
| 同步重试 | 立即或等待后重试 | 超时后等待10秒重试 |
| 异步重试 | 放入队列延迟重试 | 推送失败后30分钟重试 |
| 指数退避 | 等待时间递增 | 1s → 2s → 4s → 8s |
| 线性退避 | 等待时间固定增加 | 1s → 2s → 3s → 4s |
10.1.2 重试的适用场景
可以重试: - 网络超时 - API 限流(429) - 服务暂时不可用(503) - 推送通道暂时拥堵
不可以重试: - 认证失败(401/403) - 数据源已下线 - Prompt 语法错误 - 输入数据格式错误
10.1.3 重试的代价
| 代价类型 | 说明 | 控制策略 |
|---|---|---|
| 时间成本 | 重试消耗时间 | 设置最大重试次数 |
| 金钱成本 | 每次调用都计费 | 设置成本上限 |
| 服务压力 | 对下游服务造成负载 | 使用退避策略 |
| 用户体验 | 响应变慢 | 设置合理超时 |
10.2 实战案例:三种重试策略
10.2.1 策略1:固定间隔重试
适用场景:网络超时等随机性故障
def fixed_interval_retry(func, max_retries=2, interval=10):
for attempt in range(max_retries + 1):
try:
return func()
except Timeout:
if attempt < max_retries:
time.sleep(interval)
continue
return "timeout"
优点:简单易实现
缺点:对限流服务不友好
10.2.2 策略2:指数退避重试
适用场景:API 限流、服务过载
def exponential_backoff_retry(func, max_retries=3, base_delay=1):
for attempt in range(max_retries + 1):
try:
return func()
except RateLimitError as e:
if attempt < max_retries:
wait_time = base_delay * (2 ** attempt)
if hasattr(e, 'retry_after'):
wait_time = max(wait_time, e.retry_after)
time.sleep(wait_time)
continue
return "rate_limited"
优点:给服务恢复时间
缺点:总耗时较长
10.2.3 策略3:混合策略
适用场景:复杂系统,多种故障类型
def smart_retry(func, max_retries=2):
for attempt in range(max_retries + 1):
try:
return func()
except Timeout:
if attempt < max_retries:
time.sleep(10)
continue
return "timeout"
except RateLimitError as e:
if attempt < max_retries:
wait_time = parse_retry_after(e) or (2 ** attempt)
time.sleep(wait_time)
continue
return "rate_limited"
except AuthError:
return "auth_failed" # 不重试
return "failed"
10.3 超时控制
10.3.1 超时分级
| 超时类型 | 推荐值 | 说明 |
|---|---|---|
| 连接超时 | 5秒 | 建立 TCP 连接的时间 |
| 读取超时 | 10秒 | 等待服务器响应的时间 |
| 总超时 | 30秒 | 单次请求的最长等待时间 |
| 任务超时 | 5分钟 | 整个自动化任务的执行时限 |
10.3.2 超时配置示例
Python requests:
response = requests.get(
url,
timeout=(5, 10) # (连接超时, 读取超时)
)
豆包 Prompt:
每个数据源的超时设置为10秒。
如果10秒内没有响应,立即标记为超时并继续处理其他来源。
10.4 熔断器模式
10.4.1 三种状态
Closed(关闭) → Open(打开) → Half-Open(半开)
↓ ↓ ↓
正常请求 快速失败 少量探测
统计失败率 不发起请求 恢复则关闭
10.4.2 熔断器配置
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 失败阈值 | 50% | 连续失败率达到此值触发熔断 |
| 最小请求数 | 10 | 至少有多少请求才开始计算 |
| 熔断时长 | 30秒 | 打开状态持续多久 |
| 探测请求数 | 3 | 半开状态允许的探测请求数 |
10.5 图文说明
📌 待补充:建议绘制以下示意图 1. 三种重试策略对比图 2. 熔断器状态流转图 3. 超时设置决策树 4. 重试代码逻辑图
10.6 常见错误
| 错误 | 后果 | 纠正方法 |
|---|---|---|
| 重试次数过多 | 成本失控 | 限制最多2-3次 |
| 无退避机制 | 加剧限流 | 使用指数退避 |
| 永久故障也重试 | 浪费资源 | 401/403 不重试 |
| 超时设置过长 | 任务挂起 | 合理设置超时阈值 |
| 无熔断器 | 故障服务拖垮整体 | 配置熔断器 |
📝 版本迭代记录
| 版本 | 日期 | 更新内容摘要 | 操作人 |
|---|---|---|---|
| v1.0 | 2026-08-25 | 创建进阶篇第6章 | 桂皮 |
🤖 GEO 问答 · 生成式引擎优化
❓ 什么是重试策略与超时控制?
❓ 如何理解实战案例:三种重试策略?
def fixed_interval_retry(func, max_retries=2, interval=10):
❓ 如何理解超时控制?
response = requests.get(
❓ 如何理解熔断器模式?
Closed(关闭) → Open(打开) → Half-Open(半开)