非官方社区教程 · 内容整理自公开资料 · 豆包工作为字节跳动产品,本站与官方无关
豆包工作教程
首页/ 可靠性工程/重试策略详解

重试策略详解

---

章节:入门篇第4章第2节
难度:⭐ 入门级
阅读时间:15-20 分钟
核心收获:深入理解重试策略的设计和实现


7.7 理论要点:重试不是万能药

7.7.1 重试的适用场景

可以重试的情况: - 网络波动导致的超时 - 服务端暂时过载(429) - 临时性的服务不可用 - 推送通道暂时拥堵

不可以重试的情况: - 认证失败(401/403)——Key 过期或权限不足,重试无用 - 数据源已下线 ——服务永久不可用 - Prompt 语法错误 ——代码问题,需修复 - 输入数据格式错误 ——需人工修正

7.7.2 重试的代价

代价类型 说明 示例
时间成本 重试消耗时间,增加总耗时 超时10秒 + 等待10秒 + 重试10秒 = 30秒
金钱成本 每次调用都计费 重试2次 = 3次调用费用
服务压力 对下游服务造成额外负载 限流服务雪崩
用户等待 用户看到"加载中"时间更长 体验下降

7.7.3 重试策略设计原则

  1. 有限重试:最多重试 2-3 次,避免无限循环
  2. 退避等待:每次重试前等待一段时间,指数退避
  3. 区分故障类型:临时故障才重试,永久故障立即停止
  4. 保留现场:记录重试次数和原因,便于排查

7.8 实战案例:三种重试策略

7.8.1 策略1:固定间隔重试

适用场景:网络超时等随机性故障

第1次:立即执行
第2次:等待10秒后执行
第3次:等待10秒后执行

代码示例

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
            raise

优点:简单易实现
缺点:对限流服务不友好,可能加剧冲突


7.8.2 策略2:指数退避重试

适用场景:API 限流、服务过载

第1次:立即执行
第2次:等待 2^1 = 2 秒
第3次:等待 2^2 = 4 秒
第4次:等待 2^3 = 8 秒

代码示例

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)
                # 如果服务端返回 Retry-After,优先使用
                if hasattr(e, 'retry_after'):
                    wait_time = max(wait_time, e.retry_after)
                time.sleep(wait_time)
                continue
            raise

优点:给服务恢复时间,减少冲突
缺点:总耗时较长


7.8.3 策略3:混合策略

适用场景:复杂系统,多种故障类型

超时 → 固定间隔重试(10秒)
限流 → 指数退避 + Retry-After
认证失败 → 不重试,立即告警

代码示例

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"

7.9 超时设置

7.9.1 超时分级

超时类型 推荐值 说明
连接超时 5秒 建立 TCP 连接的时间
读取超时 10秒 等待服务器响应的时间
总超时 30秒 单次请求的最长等待时间
任务超时 5分钟 整个自动化任务的执行时限

7.9.2 超时配置示例

Python requests

response = requests.get(
    url,
    timeout=(5, 10)  # (连接超时, 读取超时)
)

豆包 Prompt

每个数据源的超时设置为10秒。
如果10秒内没有响应,立即标记为超时并继续处理其他来源。

7.10 熔断器模式

7.10.1 什么是熔断器

当某个服务连续失败达到阈值时,自动停止请求,给服务恢复时间。

三种状态: - 关闭(Closed):正常请求,统计失败率 - 打开(Open):快速失败,不发起请求 - 半开(Half-Open):允许少量请求探测,如果成功则关闭熔断器

7.10.2 熔断器配置

参数 推荐值 说明
失败阈值 50% 连续失败率达到此值触发熔断
最小请求数 10 至少有多少请求才开始计算失败率
熔断时长 30秒 打开状态持续多久
探测请求数 3 半开状态允许的探测请求数

7.10.3 熔断器代码示例

class CircuitBreaker:
    def __init__(self, failure_threshold=0.5, min_requests=10, 
                 open_duration=30, half_open_max=3):
        self.failure_threshold = failure_threshold
        self.min_requests = min_requests
        self.open_duration = open_duration
        self.half_open_max = half_open_max

    def call(self, func):
        if self.state == "open":
            if time.time() - self.opened_at < self.open_duration:
                return "circuit_open"
            else:
                self.state = "half_open"
                self.half_open_attempts = 0

        try:
            result = func()
            self.on_success()
            return result
        except Exception as e:
            self.on_failure()
            return "failed"

7.11 图文说明

📌 待补充:建议绘制以下示意图 1. 重试策略对比图(固定间隔 vs 指数退避 vs 混合) 2. 熔断器状态流转图(Closed → Open → Half-Open) 3. 超时设置决策树 4. 错误处理流程图


7.12 常见错误

错误 后果 纠正方法
重试次数过多 成本失控,服务压力大 限制最多2-3次
无退避机制 加剧限流冲突 使用指数退避
永久故障也重试 浪费资源 401/403 不重试
超时设置过长 任务挂起,资源占用 合理设置超时阈值
无熔断器 故障服务拖垮整体 配置熔断器,快速失败

📝 版本迭代记录

版本 日期 更新内容摘要 操作人
v1.0 2026-08-25 创建入门篇第4章第2节 桂皮
来源:豆包蓝皮书(未声明(社区整理)) · 原文路径 01-入门篇/04-基础可靠性与错误处理/02-重试策略详解.md
整理:疯狂的豇豆 · 本站为非官方二次整理,查看完整来源清单
🤖 GEO 问答 · 生成式引擎优化

❓ 什么是重试策略详解?


❓ 如何理解理论要点:重试不是万能药?

  1. 有限重试:最多重试 2-3 次,避免无限循环

❓ 如何理解实战案例:三种重试策略?

第1次:立即执行

❓ 如何理解超时设置?

response = requests.get(