翼度科技»论坛 编程开发 python 查看内容

Python中网络请求中Retry策略实现方式

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
网络环境的不稳定性及服务短暂不可达等因素可能导致HTTP请求失败。为了强化Python客户端的韧性和自我恢复能力,实现请求自动重试成为了一种常见的最佳实践。
在Python生态系统中,
  1. requests
复制代码
库作为处理HTTP请求的标准工具备受青睐,但它自身并未直接提供重试机制,此时,我们需要借助
  1. urllib3
复制代码
库中的
  1. Retry
复制代码
类来补充这一功能。

1. 重试机制的必要性

在大规模分布式系统环境下,服务间通信由于多种原因(如网络抖动、服务瞬时不可达等)可能面临失败的风险。
通过引入自动重试机制,能够有效提升系统的整体可靠性和容错性能,尤其对于缓解暂时性故障造成的请求失败现象,合理设计的重试策略显得至关重要。

2. 实现重试机制的基本流程

  1. requests
复制代码
库中实现请求自动重试通常遵循以下五个步骤:

  • 导入必需模块:引入
    1. requests
    复制代码
    库及其内部组件,同时包含
    1. urllib3
    复制代码
    1. Retry
    复制代码
    类。
  • 创建HTTPAdapter实例:初始化一个
    1. HTTPAdapter
    复制代码
    对象,它是自定义请求适配器。
  • 配置Retry策略:在
    1. HTTPAdapter
    复制代码
    上定义并设置重试规则,包括重试次数、状态码范围、异常类型等条件。
  • 将Adapter挂载到Session:将配置好的重试策略关联到
    1. Session
    复制代码
    对象,以便所有通过该
    1. Session
    复制代码
    发出的请求均能应用此重试策略。
  • 使用带有重试策略的Session发送请求:最后,利用配置了重试功能的
    1. Session
    复制代码
    对象执行实际的HTTP请求。

3. 使用urllib3实现重试逻辑

接下来通过具体示例详细说明如何为
  1. requests
复制代码
请求添加重试逻辑。

3.1. 导入相关模块

首先,确保正确导入所需的库和类。
  1. import requests
  2. from requests.adapters import HTTPAdapter
  3. from urllib3.util.retry import Retry
复制代码
3.2. 配置重试策略

利用
  1. Retry
复制代码
类定义一个自定义的重试策略,可以针对重试次数、指数退避因子、特定状态码列表以及允许重试的HTTP方法进行精确控制。
  1. # 定义重试策略,例如:总共重试5次,每次重试之间按指数退避,针对特定状态码进行重试,并仅限于GET和POST方法
  2. retries = Retry(
  3.     total=5,  # 总共尝试重试次数
  4.     backoff_factor=1,  # 指数退避因子,用于计算两次重试之间的等待时间
  5.     status_forcelist=[500, 502, 503, 504],  # 触发重试的状态码集合
  6.     allowed_methods=frozenset(["GET", "POST"]),  # 允许重试的HTTP方法
  7. )
复制代码
3.3. 创建HTTPAdapter并设置重试策略

创建一个
  1. HTTPAdapter
复制代码
实例,并为其配置前面定义好的重试策略。
  1. 1adapter = HTTPAdapter(max_retries=retries)  # 创建HTTPAdapter并设置最大重试次数
复制代码
3.4. 将Adapter挂载至Session

创建一个
  1. Session
复制代码
对象,并将上述已配置好重试策略的
  1. adapter
复制代码
应用于HTTP和HTTPS协议的请求。
  1. session = requests.Session()
  2. session.mount('http://', adapter)  # 对HTTP请求启用重试策略
  3. session.mount('https://', adapter)  # 对HTTPS请求启用重试策略
复制代码
3.5. 发送具有重试功能的请求

使用配置了重试策略的
  1. session
复制代码
对象向目标URL发起请求。
  1. url = "http://httpbin.org/status/500"
  2. response = session.get(url)  # 使用具有重试功能的Session对象发送请求
复制代码
4. 示例:请求一个可能返回错误的服务

以下是一个完整的示例,其中包含了错误处理机制:
  1. import requests
  2. from requests.adapters import HTTPAdapter
  3. from urllib3.util.retry import Retrydef request_with_retry(url, max_retries=5, backoff_factor=1, status_forcelist=None):    if status_forcelist is None:        status_forcelist = [500, 502, 503, 504]  # 默认重试状态码集合    session = requests.Session()    retries = Retry(total=max_retries,                    backoff_factor=backoff_factor,                    status_forcelist=status_forcelist,                    method_whitelist=["GET", "POST"])    adapter = HTTPAdapter(max_retries=retries)    session.mount('http://', adapter)    session.mount('https://', adapter)    try:        response = session.get(url)        response.raise_for_status()  # 如果响应状态码为4XX或5XX,将抛出HTTPError异常        return response    except requests.exceptions.HTTPError as e:        print(f"HTTP 错误: {e}")    except requests.exceptions.ConnectionError as e:        print(f"连接错误: {e}")    except requests.exceptions.Timeout as e:        print(f"超时错误: {e}")    except requests.exceptions.RequestException as e:        print(f"请求异常: {e}")url = "http://httpbin.org/status/500"response = request_with_retry(url)if response:    print(response.text)
复制代码
在上述示例中,当服务返回500系列错误或是发生连接异常时,
  1. request_with_retry
复制代码
函数将按照预设的最大重试次数(默认为5次)尝试重新发起请求。

结论

结合Python的
  1. requests
复制代码
库与
  1. urllib3
复制代码
  1. Retry
复制代码
类,我们可以轻松实现HTTP请求的自动重试机制,从而显著增强应用程序应对网络波动的能力。
特别是在微服务架构、API调用等场景下,这一策略尤为关键。然而,务必注意合理设定重试次数和策略,避免过度重试导致服务器负载过大。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:https://www.jb51.net/python/323407c1w.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具