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

 更新时间:2024年06月28日 08:42:45   作者:南风以南  
这篇文章主要介绍了Python中网络请求中Retry策略实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

网络环境的不稳定性及服务短暂不可达等因素可能导致HTTP请求失败。为了强化Python客户端的韧性和自我恢复能力,实现请求自动重试成为了一种常见的最佳实践。

在Python生态系统中,requests库作为处理HTTP请求的标准工具备受青睐,但它自身并未直接提供重试机制,此时,我们需要借助urllib3库中的Retry类来补充这一功能。

1. 重试机制的必要性

在大规模分布式系统环境下,服务间通信由于多种原因(如网络抖动、服务瞬时不可达等)可能面临失败的风险。

通过引入自动重试机制,能够有效提升系统的整体可靠性和容错性能,尤其对于缓解暂时性故障造成的请求失败现象,合理设计的重试策略显得至关重要。

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

requests库中实现请求自动重试通常遵循以下五个步骤:

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

3. 使用urllib3实现重试逻辑

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

3.1. 导入相关模块

首先,确保正确导入所需的库和类。

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

3.2. 配置重试策略

利用Retry类定义一个自定义的重试策略,可以针对重试次数、指数退避因子、特定状态码列表以及允许重试的HTTP方法进行精确控制。

# 定义重试策略,例如:总共重试5次,每次重试之间按指数退避,针对特定状态码进行重试,并仅限于GET和POST方法
retries = Retry(
    total=5,  # 总共尝试重试次数
    backoff_factor=1,  # 指数退避因子,用于计算两次重试之间的等待时间
    status_forcelist=[500, 502, 503, 504],  # 触发重试的状态码集合
    allowed_methods=frozenset(["GET", "POST"]),  # 允许重试的HTTP方法
)

3.3. 创建HTTPAdapter并设置重试策略

创建一个HTTPAdapter实例,并为其配置前面定义好的重试策略。

1adapter = HTTPAdapter(max_retries=retries)  # 创建HTTPAdapter并设置最大重试次数

3.4. 将Adapter挂载至Session

创建一个Session对象,并将上述已配置好重试策略的adapter应用于HTTP和HTTPS协议的请求。

session = requests.Session()
session.mount('http://', adapter)  # 对HTTP请求启用重试策略
session.mount('https://', adapter)  # 对HTTPS请求启用重试策略

3.5. 发送具有重试功能的请求

使用配置了重试策略的session对象向目标URL发起请求。

url = "http://httpbin.org/status/500"
response = session.get(url)  # 使用具有重试功能的Session对象发送请求

4. 示例:请求一个可能返回错误的服务

以下是一个完整的示例,其中包含了错误处理机制:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def 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系列错误或是发生连接异常时,request_with_retry函数将按照预设的最大重试次数(默认为5次)尝试重新发起请求。

结论

结合Python的requests库与urllib3Retry类,我们可以轻松实现HTTP请求的自动重试机制,从而显著增强应用程序应对网络波动的能力。

特别是在微服务架构、API调用等场景下,这一策略尤为关键。然而,务必注意合理设定重试次数和策略,避免过度重试导致服务器负载过大。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python 中@lazyprop 装饰器的用法

    Python 中@lazyprop 装饰器的用法

    这篇文章主要介绍了Python 中@lazyprop 装饰器的用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • PyQT5实现选项卡窗口、堆栈窗口、停靠窗口、子窗口

    PyQT5实现选项卡窗口、堆栈窗口、停靠窗口、子窗口

    这篇文章主要介绍了PyQT5实现选项卡窗口、堆栈窗口、停靠窗口、子窗口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Python元组及文件核心对象类型详解

    Python元组及文件核心对象类型详解

    本篇文章主要给大家详细讲述了Python核心对象类型之元组及文件的相关内容,对此有兴趣的学习下。
    2018-02-02
  • Python实现遍历大量表格文件并筛选出数据缺失率低的文件

    Python实现遍历大量表格文件并筛选出数据缺失率低的文件

    这篇文章主要为大家详细介绍了如何利用Python实现遍历大量表格文件并筛选出表格内数据缺失率低的文件的功能,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-05-05
  • Python 中将值附加到集合的操作方法

    Python 中将值附加到集合的操作方法

    这篇文章主要介绍了Python 中将值附加到集合的操作方法,通过使用 add() 方法或 update() 方法,你可以向 Python 中的集合中添加元素,在添加元素时,需要注意不允许重复元素和集合是无序的,本文通过示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • python 如何求N的阶乘

    python 如何求N的阶乘

    这篇文章主要介绍了python 如何求N的阶乘,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • python之cur.fetchall与cur.fetchone提取数据并统计处理操作

    python之cur.fetchall与cur.fetchone提取数据并统计处理操作

    这篇文章主要介绍了python之cur.fetchall与cur.fetchone提取数据并统计处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • tensorflow从ckpt和从.pb文件读取变量的值方式

    tensorflow从ckpt和从.pb文件读取变量的值方式

    这篇文章主要介绍了tensorflow从ckpt和从.pb文件读取变量的值方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • django做form表单的数据验证过程详解

    django做form表单的数据验证过程详解

    这篇文章主要介绍了django做form表单的数据验证过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python数据可视化:幂律分布实例详解

    Python数据可视化:幂律分布实例详解

    今天小编就为大家分享一篇Python数据可视化:幂律分布实例详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12

最新评论