直接用 requests.get() 调用第三方 API 容易失败,因网络抖动、限流、DNS超时、SSL失败等瞬时故障常见,而 requests 默认无重试机制;应使用 tenacity 实现按异常类型、状态码等条件的可控重试,并避免对客户端错误或非幂等请求重试。

为什么直接用 requests.get() 调用第三方API容易失败?
网络抖动、目标服务限流、DNS解析超时、SSL握手失败——这些在生产环境里太常见了。Flask 本身不处理重试,requests.get() 默认失败就抛异常,没重试逻辑。你看到的 ConnectionError、Timeout、502 Bad Gateway 往往不是永久性错误,重试 2–3 次大概率能成功。
用 tenacity 实现可配置的重试逻辑(推荐)
tenacity 是目前最轻量又灵活的 Python 重试库,比手写 while + try/except 更可靠,也比 retrying(已停更)更活跃。它支持按异常类型、返回状态码、耗时等条件触发重试。
- 安装:
pip install tenacity - 基本用法:对请求函数加装饰器,比如重试 3 次,指数退避,只对
requests.exceptions.ConnectionError和requests.exceptions.Timeout重试 - 注意:别对
400 Bad Request或401 Unauthorized重试——这是客户端错误,重试没意义 - 示例中用
stop_after_attempt(3)控制最大尝试次数,wait_exponential(multiplier=1, min=1, max=10)表示第 1 次等 1s,第 2 次等 2s,第 3 次等 4s(上限 10s)
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import requests
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=10),
retry=retry_if_exception_type((
requests.exceptions.ConnectionError,
requests.exceptions.Timeout
))
)
def call_third_party_api():
resp = requests.get("https://api.example.com/data", timeout=5)
resp.raise_for_status()
return resp.json()
在 Flask 视图中安全集成重试逻辑
别把重试逻辑塞进路由函数体里——那样会污染业务代码,也不利于单元测试。应该封装成独立函数或服务类,并在视图中调用。还要注意两点:超时时间要小于 Flask 的 timeout(如 Nginx 的 proxy_read_timeout),否则重试还没完,网关就先断连了;另外,重试期间如果用户取消请求(如关闭页面),requests 不会自动中断,得显式传 timeout 并配合 session 的 mount 做连接池控制。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 建议为第三方 API 单独建
session,复用连接,避免每次新建 TCP 连接 - 给
requests.get()显式设timeout=(3, 5):3 秒连通,5 秒读取,总耗时可控 - 如果重试后仍失败,捕获
tenacity.RetryError并返回友好错误,而不是让 Flask 500 崩溃 - 别在重试装饰器里直接写日志——重试过程中的中间失败不该刷满日志,建议用
before_retry回调做轻量记录
哪些情况不该加重试?
重试不是万能膏药。以下情况加了反而有害:
立即学习“Python免费学习笔记(深入)”;
- HTTP 状态码是
400、401、403、404、422—— 这些是客户端问题,改参数才有用 - 请求本身是 POST/PUT/DELETE 且非幂等 —— 比如扣款接口,重试可能重复扣钱
- 第三方明确返回
Retry-After头但你忽略它,硬用固定退避策略 - 你的上游服务(如负载均衡)本身已有重试机制,再叠加容易放大雪崩风险
真正关键的是区分“瞬时故障”和“语义错误”。前者靠重试救,后者靠修复输入或联系对方查原因。重试次数设成 3 是经验平衡点:太少兜不住抖动,太多拖慢响应且增加对方压力。

















