Skip to main content

funboost-advanced-retry

当需要配置 funboost 的高级重试策略时使用。触发场景:指数退避重试、死信队列、熔断器、任务去重过滤、自定义错误处理。关键词:retry, max_retry_times, dead letter, DLX, exponential backoff, circuit breaker, is_using_advanced_retry, is_push_to_dlx_queue_when_retry_max_times, do_task_filtering, 重试, 死信, 熔断。

Source facts

Repository
ydf0509/funboost
Last source activity
August 4, 2026 at 14:03
Detected SKILL.md language
Chinese
Stars
892
Forks
165

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
funboost-advanced-retry
description
当需要配置 funboost 的高级重试策略时使用。触发场景:指数退避重试、死信队列、熔断器、任务去重过滤、自定义错误处理。关键词:retry, max_retry_times, dead letter, DLX, exponential backoff, circuit breaker, is_using_advanced_retry, is_push_to_dlx_queue_when_retry_max_times, do_task_filtering, 重试, 死信, 熔断。
# Funboost 高级重试与容错 ## 概述 Funboost 提供多层错误恢复能力:自动重试、指数退避、死信队列、熔断器和任务去重。 **核心原则:** 通过 BoosterParams 声明式配置重试行为——不要手动编写 try/except 重试循环。 ## 适用场景 - 任务可能因瞬态故障失败(网络、API 限流) - 需要重试间递增等待时间(指数退避) - 希望最终失败的任务路由到死信队列 - 需要熔断器保护下游服务 - 需要防止同一任务重复执行 ## 速查表 | 功能 | BoosterParams 字段 | 默认值 | |------|-------------------|--------| | 最大重试次数 | `max_retry_times` | 3(最多重试 N 次 + 首次执行 = 共 N+1 次机会) | | 指数退避 | `is_using_advanced_retry` | False | | 死信队列 | `is_push_to_dlx_queue_when_retry_max_times` | False | | 任务去重 | `do_task_filtering` | False | | 函数超时 | `function_timeout` | None | ## 基础重试 ```python from funboost import boost, BoosterParams @boost(BoosterParams( queue_name="fragile_task", max_retry_times=5, # 异常时最多重试 5 次 function_timeout=30, # 单次执行超过 30 秒则终止 )) def call_external_api(url: str): import requests resp = requests.get(url, timeout=10) resp.raise_for_status() return resp.json() ``` > `max_retry_times=N` 表示最多重试 N 次,加上首次执行,共 N+1 次执行机会。 > 当 `is_using_advanced_retry=False`(默认)时,失败后会在**同一线程内立即重试**,无等待间隔。只有启用高级重试后才走指数退避。 ## 指数退避重试 ```python @boost(BoosterParams( queue_name="backoff_task", max_retry_times=5, is_using_advanced_retry=True, # 启用指数退避 )) def rate_limited_api(endpoint: str): """指数退避:间隔 = min(base * 2^n, max_interval),默认 1s,2s,4s,8s...封顶60s""" import requests resp = requests.get(endpoint) if resp.status_code == 429: raise Exception("被限流了") return resp.json() ``` ### advanced_retry_config 参数 通过 `BoosterParams.advanced_retry_config` 字典自定义退避行为: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `retry_mode` | str | `"sleep"` | `"sleep"` = 当前线程 sleep 等待后重试;`"requeue"` = 发回队列(附带 countdown),释放线程 | | `retry_base_interval` | float | `1.0` | 退避基础间隔(秒) | | `retry_multiplier` | float | `2.0` | 退避倍数(每次重试间隔乘以此值) | | `retry_max_interval` | float | `60.0` | 退避最大间隔(秒),封顶值 | | `retry_jitter` | bool | `False` | 是否加随机抖动,防止多消费者同时重试(惊群) | ```python @boost(BoosterParams( queue_name="custom_backoff_task", max_retry_times=8, is_using_advanced_retry=True, advanced_retry_config={ "retry_mode": "requeue", # 重试时发回队列,释放线程资源 "retry_base_interval": 2.0, # 起始等 2 秒 "retry_multiplier": 3.0, # 每次 x3:2s, 6s, 18s, 54s, 60s(封顶)... "retry_max_interval": 60.0, # 最大 60 秒 "retry_jitter": True, # 加随机抖动 }, )) def custom_backoff_task(data: dict): process(data) ``` **两种 retry_mode 的区别:** - `"sleep"` — 简单场景,线程被占用直到重试完成;适合并发数充足时 - `"requeue"` — 消息重新入队(带 countdown 延迟),当前线程立即释放去处理其他消息;适合高并发/长退避场景 ## 死信队列 (DLX) 开启 `is_push_to_dlx_queue_when_retry_max_times=True` 后,重试耗尽的任务推送到死信队列: ```python @boost(BoosterParams( queue_name="important_task", max_retry_times=3, is_push_to_dlx_queue_when_retry_max_times=True, # -> important_task_dlx )) def process_payment(order_id: str, amount: float): """3 次重试全部失败后,消息进入 'important_task_dlx' 队列""" charge(order_id, amount) ``` ## 主动控制重试/入队的异常类 funboost 提供 3 个内置异常类,可在消费函数中主动 `raise` 来控制任务流向: | 异常类 | 行为 | 是否计入 max_retry_times | |--------|------|--------------------------| | `ExceptionForRequeue` | 立即将消息重新放回当前队列(不等待、不计重试次数) | **否** | | `ExceptionForPushToDlxqueue` | 立即将消息推入死信队列 `{queue_name}_dlx` | — | | `ExceptionForRetry` | 语义标记(任意异常本就触发重试,此类仅增强语义清晰度) | 是 | ```python from funboost import ExceptionForRequeue, ExceptionForPushToDlxqueue @boost(BoosterParams(queue_name="controlled_retry", broker_kind=BrokerEnum.REDIS_ACK_ABLE)) def process_order(order_id): status = check_order_status(order_id) if status == "not_ready": raise ExceptionForRequeue() # 还没准备好,重回队列稍后再试 if status == "invalid": raise ExceptionForPushToDlxqueue() # 无效订单,直接进死信 # 正常处理... ``` > **注意:** `ExceptionForRequeue` 不受 `max_retry_times` 限制,消息会无限重回队列直到不再抛此异常。使用时需确保有退出条件,避免无限循环。 ## 熔断器 (Mixin) 连续失败达阈值时熔断(OPEN 状态下消费端 `_submit_task` 阻塞等待恢复,消息暂留队列;不影响发布端 `push`/`publish`),防止级联故障: ```python from funboost import boost, BoosterParams from funboost.contrib.override_publisher_consumer_cls.circuit_breaker_mixin import CircuitBreakerConsumerMixin @boost(BoosterParams( queue_name="protected_task", consumer_override_cls=CircuitBreakerConsumerMixin, user_options={ "circuit_breaker_options": { "failure_threshold": 5, # 连续 5 次失败后熔断(OPEN) "recovery_timeout": 60, # 60 秒后进入半开(HALF_OPEN)试探 }, }, )) def call_fragile_service(data: dict): return external_service.process(data) ``` ## 任务去重(过滤) 消费端过滤:相同入参的任务**完成一次消费周期后**,再次发布会被跳过(需 Redis): ```python @boost(BoosterParams( queue_name="dedup_task", do_task_filtering=True, # 需要 Redis 配置 )) def send_notification(user_id: int, message: str): """相同 (user_id, message) 组合完成消费后不会重复处理""" notify(user_id, message) ``` ## 获取重试上下文 ```python from funboost import fct @boost(BoosterParams(queue_name="ctx_retry", max_retry_times=3)) def task_with_context(url: str): run_times = fct.function_result_status.run_times if run_times > 1: print(f"第 {run_times} 次执行(第 {run_times - 1} 次重试)") fetch(url) ``` ## 组合多种策略 ```python @boost(BoosterParams( queue_name="resilient_pipeline", max_retry_times=5, is_using_advanced_retry=True, is_push_to_dlx_queue_when_retry_max_times=True, function_timeout=60, do_task_filtering=True, )) def resilient_task(job_id: str, payload: dict): """ - 指数退避重试 5 次 - 每次超时 60 秒 - 相同入参完成消费后自动跳过 - 重试耗尽后进入死信队列 """ process(job_id, payload) ``` ## 常见错误 | 错误 | 修正 | |------|------| | `max_retries=5` | 正确字段:`max_retry_times=5` | | `timeout=30` | 正确字段:`function_timeout=30` | | 手写重试循环 | 让 funboost 通过 BoosterParams 处理重试 | | `do_task_filtering=True` 但没配 Redis | 任务过滤依赖 Redis | | 搞混 DLX 队列名 | 自动命名为 `{原队列名}_dlx` | | 用 `try/except` 吞掉所有异常 | 让异常正常抛出,funboost 才能执行重试 | ## 相关 Skill - `developing-funboost-mixin` — Consumer/Publisher Mixin 扩展 - `funboost-troubleshooting` — 排错与 FAQ
View on GitHub