安全重试需设最大次数、只捕获可重试异常(如requestexception)、指数退避延迟、每次重试重置状态(如重建session、刷新token),避免无限循环与雪崩。

用 while 循环实现安全的重试机制,关键不是“能重试”,而是“不瞎重试”——既要防无限循环,又要区分哪些错误值得重试、哪些该立刻放弃。
必须设退出条件,不能写 while True
无限制的 while True 是高危写法。真实环境中网络可能持续中断、URL 永远拼错、服务永久下线,若没兜底,程序就卡死或耗尽资源。
- 用计数器控制最大尝试次数,比如
retry_count = 0和max_retries = 3 - 每次循环开头先检查:
if retry_count >= max_retries: raise Exception("重试超限") - 成功获取有效响应后,立刻
break,不等下一轮
只捕获可重试的异常,放过致命错误
不是所有异常都适合重试。键盘中断(KeyboardInterrupt)、内存不足(MemoryError)、语法错误(SyntaxError)重试毫无意义,反而掩盖问题。
- 专注捕获网络相关异常:
requests.exceptions.RequestException(它已涵盖超时、连接失败、HTTP 错误等) - 业务层失败也要主动转为可重试异常:比如
response.status_code == 503或resp.json()报JSONDecodeError,都应raise RequestException - 避免写
except Exception:——太宽泛,会吞掉不该忽略的问题
每次重试前加延迟,且延迟要递增
立刻重试不仅无效,还可能加剧服务压力(雪崩效应)。指数退避是通用解法:第 1 次等 1 秒,第 2 次等 2 秒,第 3 次等 4 秒……再加点随机抖动,避免大量请求同时涌向服务器。
- 延迟公式建议:
time.sleep((2 ** retry_count) + random.uniform(0, 1)) - 若响应头含
Retry-After,优先按它给的时间休眠(尤其对 503 响应) - 延迟必须放在
except块末尾、retry_count += 1之后
重试不是简单“再跑一遍”,状态要重置
如果请求带 token、动态 headers 或临时 session,重试时不能复用旧对象——token 可能已过期,session 可能已断连。
- 每次循环内重建
requests.Session()或重新生成 headers - 不要在循环外定义
session = requests.Session()后反复调用session.get()——底层连接可能已失效 - 若需刷新认证,把 token 获取逻辑也放进循环体内(例如调用
get_fresh_token())











