問題描述
在使用域名請求接口時,有兩個地方會出現超時,連接超時和讀取超時
關於接口服務器響應超時
可以在本地搭建測試環境。
- 搭建測試接口服務器
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
- 測試代碼
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()
- 測試讀取超時
運行測試代碼之后,出現以下情況
從上面的日志信息,可以看出API請求了3次,但是因為加了一次重試,web服務接受了4次請求,最后的錯誤是讀取超時錯誤。
也就是說 requests.exceptions.ConnectionError
異常捕獲到了讀取超時錯誤。
測試連接超時錯誤
將2的代碼改為一下方式,可以看到連接超時錯誤,元祖的第一個元素是連接超時
- res = session.get(url, timeout=(2, 3))
+ res = session.get(url, timeout=(0.0001, 3))
web服務器沒有接收到任何請求
從上述日志可以看出,如果是連接超時的錯誤,服務器是不會接收到請求的,而且會被requests.exceptions.Timeout
捕獲到。
還有網關的問題
如果requests連接到網關之后,網關請求后面的數據,此時超時的話,不會出現連接超時異常,只會出現讀取超
時,一個很簡單的例子就是:還是上面的代碼,測試讀取超時處,打開Fiddler,此時會看到即使連接超時>
設置的非常非常小,還是不會出現連接超時的異常,能成功連接服務器,之后會出現讀取超時。跟我們預想的情況不
一樣。
所以我們需要非常小心這樣的情況,在連接到網關之后,網關找相應的服務,服務進行業務操作,服務返回給網關,網
關返回給requests,這一段時間都是屬於requests的讀取超時內的