zoukankan      html  css  js  c++  java
  • requests请求超时尝试重连的3种方式

    参考文档

    https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry
    https://blog.csdn.net/shengruxiahua2571/article/details/103165315/
    

    了解

    连接超时 ==> 发起请求连接到建立连接之间的最大时长
    读取超时 ==> 连接成功开始到服务器返回响应之间等待的最大时长
    

    代码示例

    import traceback
    import time
    from urllib3.util.retry import Retry
    from requests.adapters import HTTPAdapter
    retries = Retry(total=3,
                            backoff_factor=0.1,
                            status_forcelist=[ 500, 502, 503, 504 ])
    s = requests.Session()
    s.mount('http://', HTTPAdapter(max_retries=retries))
    s.mount('https://', HTTPAdapter(max_retries=retries))
    count = 0
    while True:
        if count < 3:
            try:
                file = s.get(url, stream=True, timeout=5)
                return file.content
            except:
                print('Retry!')
                time.sleep(3)
                traceback.print_exc()
                count += 1
                continue
        else:
            print('Fail!')
            break
        
    # 相关Retry参数说明
    total  允许的重试次数
    connect 要重试的连接相关错误数
    read  读取错误时重试多少次
    redirect  要执行的重定向数
    status_forcelist 一组我们应该强制重试的HTTP状态代码
    backoff_factor 在第二次尝试后在尝试之间应用的退避因素(大多数错误会立即通过第二次尝试解决,没有延迟)
    raise_on_redirect  如果重定向次数用尽,是否引发 MaxRetryError 或返回响应代码在 3xx 范围内的响应。
    raise_on_status  类似于raise_on_redirect:如果状态在status_forcelist范围内并且重试已经用尽,我们是否应该引发异常或返回响应。
    

    结合项目需求使用的两种方法

    方法一,普通循环请求判断

        def connection_demo(self, request):
            start_time = datetime.now()
            while True:
                ...  # 省略其它代码部分
                    num_times = 0
                    session = requests.Session()   # 推荐使用session可以提高访问速度
                    while num_times < 3:
                        try:
                            result = session.get(url=url, verify=False, timeout=5)
                            if result.status_code == 200:
                                break
                        except requests.exceptions.RequestException:  # 如果HTTP请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常
                            num_times += 1
                            continue
                    if num_times < 3:
                        break
                    else:
                        raise VtuneTimeOutException
                ...  # 省略其它代码部分
            return redirect_url
    

    方法二,requests的retry

    import requests
    from urllib3.util.retry import Retry
    from requests.adapters import HTTPAdapter
    
    def connection_demo(self, request):
        start_time = datetime.now()
        while True:
           ... # 省略其余代码部分
                req = requests.Session()
                retries = Retry(total=3,
                                backoff_factor=0.1,
                                status_forcelist=[500, 502, 503, 504])
                req.mount('https://', HTTPAdapter(max_retries=retries))
                try:
                    result = req.get(url=url, verify=False, timeout=5)
                    if result.status_code == 200:
                        break
                    else:
                        raise VtuneTimeOutException
                except requests.exceptions.RequestException:
                    raise VtuneTimeOutException
            ... # 省略其余代码部分
        return redirect_url
    

    方法3,装饰器retry

    pip install retry
    自行百度
    

    总结

    需求是:后端视图代码请求由内部生成并存储到数据库中的一个url,看是否通再将url返回给前端,3次重连,根据requests的status_code为200来判断是否成功,
    状态码200成功则结束,其它状态码不成功则继续,
    并且在3次重连内,有超时等问题都不希望让其抛出错误,等3次重连结束后,再判断是否都不成功再抛出错误。使用第二种方法有点小bug,
    具体还是要结合项目,之前没有加status_forcelist这个玩意,导致有一次请求得到503,页面报错了,但是因为有三次重连的机制,
    报错了还继续执行成功了。所以后面加了status_forcelist,但是还有异常捕获的问题,因为只要有一次超时或其它问题,
    都会被捕获抛异常,那样也会遇到报错了还继续执行成功了的问题。
    所以我使用了第一种方式写法,当然了还是要结合项目需求来。
    

    -------------------------------------------

    个性签名:代码过万,键盘敲烂!!!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    mysql随手记
    Exception 和 RuntimeException区别
    数据结构与算法
    Idea快捷键
    eclipse快捷键
    了解Lua语言中的_index,newindex,rawget和rawset
    Cocos2d-x CCNotificationCenter 通知中心
    LUA-赋值语句
    CCOrbitCamera:create
    类型和值
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/15716501.html
Copyright © 2011-2022 走看看