對python3下的requests使用并不是很熟練,今天稍微用了下,請求幾次下來后發現出現連接超時的異常,上網查了下,找到了一個還算中肯的解決方法。
retrying是python的一個自帶的重試包
導入方式:
from retrying import retry
簡單使用
retrying 這個包的用法原理就是在你不知道那段代碼塊是否會發生異常,若發生異常,可以再次執行該段的代碼塊,如果沒有發生異常,那么就繼續執行往下執行代碼塊
以前你的代碼可能是這樣寫的:
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)
上面的是簡單的用法,你可以試下,下面是一些可選參數的使用方式。
用來設定最大的嘗試次數,超過該次數就停止重試
超過時間段,函數就不會再執行了
wait_random_min和wait_random_max
用隨機的方式產生兩次retrying之間的停留時間
補充:python中Requests的重試機制
requests原生支持
import requests
from requests.adapters import HTTPAdapter
s = requests.Session()
# 重試次數為3
s.mount('http://', HTTPAdapter(max_retries=3))
s.mount('https://', HTTPAdapter(max_retries=3))
# 超時時間為5s
s.get('http://example.com', timeout=5)
requests使用的重試算法:BackOff(指數退避算法)
什么是指數退避算法
在wiki當中對指數退避算法的介紹是:
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.
翻譯成中文的意思大概是“在各種的計算機網絡中,二進制指數后退或是截斷的二進制指數后退使用于一種隔離同一數據塊重復傳輸的算法,常常做為網絡避免沖突的一部分”
比如說在我們的服務調用過程中發生了調用失敗,系統要對失敗的資源進行重試,那么這個重試的時間如何把握,使用指數退避算法我們可以在某一范圍內隨機對失敗的資源發起重試,并且隨著失敗次數的增加長,重試時間也會隨著指數的增加而增加。
當然,指數退避算法并沒有人上面說的那么簡單,想具體了解的可以具體wiki上的介紹
當系統每次調用失敗的時候,我們都會產生一個新的集合,集合的內容是0~2n-1,n代表調用失敗的次數
第一次失敗 集合為 0,1
第二次失敗 集合為 0,1,2,3
第三次失敗 集合為 0,1,2,3,4,5,6,7
在集合中隨機選出一個值記為R,下次重試時間就是R*基本退避時間(對應在指數退避算法中爭用期) 當然,為了防止系統無限的重試下去,我們會指數重新的最大次數
為什么要使用指數退避算法
使用指數退避算法,可以防止連續的失敗,從某方面講也可以減輕失敗服務的壓力,試想一下,如果一個服務提供者的服務在某一時間發生了異常、超時或是網絡抖動,那么頻繁的重試所得到的結果也大致都是失敗。這樣的頻繁的重試不僅沒有效果,反而還會增服務的負擔。
應用場景有哪些
接入三方支付服務,在三方支付提供的接入接口規范中,服務方交易結束結果通知和商戶主動查詢交易結果都用到重發機制
在app應用中,很多場景會遇到輪詢一類的問題,輪詢對于app性能和電量的消耗都過大。
代碼示例


以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- python爬蟲之利用Selenium+Requests爬取拉勾網
- Python requests timeout的設置
- python+requests+pytest接口自動化的實現示例
- Python requests庫參數提交的注意事項總結
- python urllib.request模塊的使用詳解
- python requests完成接口文件上傳的案例
- python爬取豆瓣電影排行榜(requests)的示例代碼
- requests在python中發送請求的實例講解
- python 實現Requests發送帶cookies的請求
- python軟件測試Jmeter性能測試JDBC Request(結合數據庫)的使用詳解
- python requests庫的使用
- python實現文件+參數發送request的實例代碼
- Python爬蟲基礎之requestes模塊