對python3下的requests使用并不是很熟練,今天稍微用了下,請求幾次下來后發(fā)現(xiàn)出現(xiàn)連接超時(shí)的異常,上網(wǎng)查了下,找到了一個(gè)還算中肯的解決方法。
retrying是python的一個(gè)自帶的重試包
導(dǎo)入方式:
from retrying import retry
簡單使用
retrying 這個(gè)包的用法原理就是在你不知道那段代碼塊是否會發(fā)生異常,若發(fā)生異常,可以再次執(zhí)行該段的代碼塊,如果沒有發(fā)生異常,那么就繼續(xù)執(zhí)行往下執(zhí)行代碼塊
以前你的代碼可能是這樣寫的:
def get_html(url):
pass
def log_error(url):
pass
url = ""
try:
get_page(url)
except:
log_error(url)
也有可能是這樣子寫的:
# 請求超過十次就放棄
attempts = 0
success = False
while attempts 10 and not success:
try:
get_html(url)
success = True
except:
attempts += 1
if attempts == 10:
break
使用 retrying 的寫法:
import random
from retrying import retry
@retry()
def do_something_unreliable():
if random.randint(0, 10) > 1:
raise IOError("Broken sauce, everything is hosed!!!111one")
else:
return "Awesome sauce!"
result = do_something_unreliable()
print(result)
上面的是簡單的用法,你可以試下,下面是一些可選參數(shù)的使用方式。
用來設(shè)定最大的嘗試次數(shù),超過該次數(shù)就停止重試
超過時(shí)間段,函數(shù)就不會再執(zhí)行了
wait_random_min和wait_random_max
用隨機(jī)的方式產(chǎn)生兩次retrying之間的停留時(shí)間
補(bǔ)充:python中Requests的重試機(jī)制
requests原生支持
import requests
from requests.adapters import HTTPAdapter
s = requests.Session()
# 重試次數(shù)為3
s.mount('http://', HTTPAdapter(max_retries=3))
s.mount('https://', HTTPAdapter(max_retries=3))
# 超時(shí)時(shí)間為5s
s.get('http://example.com', timeout=5)
requests使用的重試算法:BackOff(指數(shù)退避算法)
什么是指數(shù)退避算法
在wiki當(dāng)中對指數(shù)退避算法的介紹是:
In a variety of computer networks, binary exponential backoff or truncated binary exponential backoff refers to an algorithm used to space out repeated retransmissions of the same block of data, often as part of network congestion avoidance.
翻譯成中文的意思大概是“在各種的計(jì)算機(jī)網(wǎng)絡(luò)中,二進(jìn)制指數(shù)后退或是截?cái)嗟亩M(jìn)制指數(shù)后退使用于一種隔離同一數(shù)據(jù)塊重復(fù)傳輸?shù)乃惴?,常常做為網(wǎng)絡(luò)避免沖突的一部分”
比如說在我們的服務(wù)調(diào)用過程中發(fā)生了調(diào)用失敗,系統(tǒng)要對失敗的資源進(jìn)行重試,那么這個(gè)重試的時(shí)間如何把握,使用指數(shù)退避算法我們可以在某一范圍內(nèi)隨機(jī)對失敗的資源發(fā)起重試,并且隨著失敗次數(shù)的增加長,重試時(shí)間也會隨著指數(shù)的增加而增加。
當(dāng)然,指數(shù)退避算法并沒有人上面說的那么簡單,想具體了解的可以具體wiki上的介紹
當(dāng)系統(tǒng)每次調(diào)用失敗的時(shí)候,我們都會產(chǎn)生一個(gè)新的集合,集合的內(nèi)容是0~2n-1,n代表調(diào)用失敗的次數(shù)
第一次失敗 集合為 0,1
第二次失敗 集合為 0,1,2,3
第三次失敗 集合為 0,1,2,3,4,5,6,7
在集合中隨機(jī)選出一個(gè)值記為R,下次重試時(shí)間就是R*基本退避時(shí)間(對應(yīng)在指數(shù)退避算法中爭用期) 當(dāng)然,為了防止系統(tǒng)無限的重試下去,我們會指數(shù)重新的最大次數(shù)
為什么要使用指數(shù)退避算法
使用指數(shù)退避算法,可以防止連續(xù)的失敗,從某方面講也可以減輕失敗服務(wù)的壓力,試想一下,如果一個(gè)服務(wù)提供者的服務(wù)在某一時(shí)間發(fā)生了異常、超時(shí)或是網(wǎng)絡(luò)抖動(dòng),那么頻繁的重試所得到的結(jié)果也大致都是失敗。這樣的頻繁的重試不僅沒有效果,反而還會增服務(wù)的負(fù)擔(dān)。
應(yīng)用場景有哪些
接入三方支付服務(wù),在三方支付提供的接入接口規(guī)范中,服務(wù)方交易結(jié)束結(jié)果通知和商戶主動(dòng)查詢交易結(jié)果都用到重發(fā)機(jī)制
在app應(yīng)用中,很多場景會遇到輪詢一類的問題,輪詢對于app性能和電量的消耗都過大。
代碼示例
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- python爬蟲之利用Selenium+Requests爬取拉勾網(wǎng)
- Python requests timeout的設(shè)置
- python+requests+pytest接口自動(dòng)化的實(shí)現(xiàn)示例
- Python requests庫參數(shù)提交的注意事項(xiàng)總結(jié)
- python urllib.request模塊的使用詳解
- python requests完成接口文件上傳的案例
- python爬取豆瓣電影排行榜(requests)的示例代碼
- requests在python中發(fā)送請求的實(shí)例講解
- python 實(shí)現(xiàn)Requests發(fā)送帶cookies的請求
- python軟件測試Jmeter性能測試JDBC Request(結(jié)合數(shù)據(jù)庫)的使用詳解
- python requests庫的使用
- python實(shí)現(xiàn)文件+參數(shù)發(fā)送request的實(shí)例代碼
- Python爬蟲基礎(chǔ)之requestes模塊