python requests的超時和重試


問題描述

在使用域名請求接口時,有兩個地方會出現超時,連接超時讀取超時

關於接口服務器響應超時

可以在本地搭建測試環境。

  1. 搭建測試接口服務器
from bottle import Bottle, run
import time

app = Bottle()

# URL地址為 /sleep/需要睡眠的時長
@app.route("/sleep/<sleep:int>")
def spleepDef(sleep):
    time.sleep(sleep)
    return "sleep time is %s" % sleep
# 可更改 port 為需要監聽的接口
run(app, host="0.0.0.0", port=8888, debug=True, reloader=True)

需要有bottle包,使用以下命令安裝

pip install bottle
  1. 測試代碼
from requests.adapters import HTTPAdapter
from requests import Session
import requests

session = Session()
# request 重試配置 重試一次
# 如果發生讀取異常,則請求時間為 (重試次數+1) * 超時時間
# 例如 超時3秒,重試1次,則出現異常是請求時間為 6秒
session.mount("http://", HTTPAdapter(max_retries=1))
session.mount("https://", HTTPAdapter(max_retries=1))

for i in range(1, 4): # 請求3次,休眠時間依次增加
    url = "http://dn03:8888/sleep/%s" % i
    print(url)
    try:
        res = session.get(url, timeout=(2, 3))
    except requests.exceptions.Timeout as e:
        print("連接超時 %s" % e)
    except requests.exceptions.ConnectionError as e:
         print("讀取數據超時 %s" % e)
    else:
        print(res.text)
    print()
  1. 測試讀取超時

運行測試代碼之后,出現以下情況

web服務器
請求測試
即使中斷了請求第二次也是會返回信息,但是requests也不會接受了
使用wireshark抓取的請求信息

從上面的日志信息,可以看出API請求了3次,但是因為加了一次重試,web服務接受了4次請求,最后的錯誤是讀取超時錯誤。

也就是說 requests.exceptions.ConnectionError 異常捕獲到了讀取超時錯誤。

測試連接超時錯誤

將2的代碼改為一下方式,可以看到連接超時錯誤,元祖的第一個元素是連接超時

- res = session.get(url, timeout=(2, 3))
+ res = session.get(url, timeout=(0.0001, 3))

web服務器沒有接收到任何請求

請求測試

使用wireshark抓取的請求

從上述日志可以看出,如果是連接超時的錯誤,服務器是不會接收到請求的,而且會被requests.exceptions.Timeout捕獲到。

還有網關的問題

如果requests連接到網關之后,網關請求后面的數據,此時超時的話,不會出現連接超時異常,只會出現讀取超
,一個很簡單的例子就是:還是上面的代碼,測試讀取超時處,打開Fiddler,此時會看到即使連接超時>
設置的非常非常小,還是不會出現連接超時的異常,能成功連接服務器,之后會出現讀取超時。跟我們預想的情況不
一樣。

所以我們需要非常小心這樣的情況,在連接到網關之后,網關找相應的服務,服務進行業務操作,服務返回給網關,網
關返回給requests,這一段時間都是屬於requests的讀取超時內的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM