軟硬件環境
-
windows 11 64bits
-
python 3.6
-
tenacity
簡介
在實際應用中,經常會碰到在web
請求時,因爲網絡的不穩定,會有請求超時的問題,這時候,一般都是自己去實現重試請求的邏輯,直到得到響應或者超時。雖然這樣的邏輯並不複雜,但是代碼寫起來卻不那麼優雅,不那麼pythonic
。
tenacity
是一個重試庫,使用python
語言編寫,它能夠讓我們在任務的重試操作中變得非常簡單,使用的是Apache 2.0
開源協議。
tenacity
有如下特性
-
裝飾器
API
-
可指定停止條件
-
可指定等待條件
-
自定義異常時的重試
-
自定義特定返回值的重試
-
在協程中使用
模塊安裝
使用pip
安裝tenacity
pip install tenacity
示例代碼
無條件重試
這是tenacity
最基本的用法,在task
方法中使用裝飾器@retry
,當task
出現異常時,我們就重新運行task
,這裏沒加任何限制,如果異常一直出現,task
就會一直運行下去
from tenacity import retry import time @retry def task(): print("task running ... ") time.sleep(1) raise Exception task()
執行上述代碼,得到
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
task running ...
.
.
.
設定停止條件
通過方法stop_after_attempt
指定重試的次數,如下的3次
import time from tenacity import retry, stop_after_attempt @retry(stop=stop_after_attempt(3)) def task(): print("task running ... ") time.sleep(1) raise Exception task()
重試三次之後就報錯了
或者使用方法stop_after_delay
指定重試多長時候後停止,如下的3秒
from tenacity import retry, stop_after_delay @retry(stop=stop_after_delay(3)) def task(): print("task running ... ") raise Exception task()
一直重試很多次,3秒後還沒成功,就結束重試
還可以將stop_after_delay
和stop_after_attempt
組合起來用,如下的代碼,只要其中一個條件滿足,task
就停止運行
import time from tenacity import retry, stop_after_attempt, stop_after_delay @retry(stop=(stop_after_delay(10) | stop_after_attempt(5))) def task(): print("task running ... ") time.sleep(1) raise Exception task()
設定等待時間
使用方法wait_fixed
來指定重試時等待的時間,如下代碼中的3秒,每一次重試task
前都要等待3秒鐘
from tenacity import retry, wait_fixed @retry(wait=wait_fixed(3)) def task(): print("task running ... ") raise Exception task()
如下,可以看到,每隔3秒重試一次
使用方法wait_random(min, max)
,在min
和max
之間隨機取值,每一次task
重試前就等待這個隨機值,單位是秒
from tenacity import retry, wait_random @retry(wait=wait_random(min=1, max=3)) def task(): print("task running ... ") raise Exception task()
時間有1 2 3s的
當然,上面2中種方法也是可以結合起來用的
from tenacity import retry, wait_fixed, wait_random @retry(wait=wait_fixed(3) + wait_random(0, 2)) def task(): print("task running ... ") raise Exception task()
什麼情況下重試
可以通過retry_if_exception_type
指定特定類型的異常出現時,任務才重試
from tenacity import retry, retry_if_exception_type @retry(retry=retry_if_exception_type(IOError)) def task(): print("task running ... ") raise Exception task()
重試錯誤後的異常拋出
出現異常後,會進行重試,若重試後還是失敗,默認情況下,往上拋出的異常會變成RetryError
,而不是最根本的原因。因此可以加一個參數reraise=True
,使得當重試失敗後,往外拋出的異常還是原來的那個異常。
from tenacity import retry, stop_after_attempt @retry(stop=stop_after_attempt(3), reraise=True) def task(): print("task running ... ") raise Exception task()
默認是false,false是重試錯誤
在重試前執行動作
tenacity
可以在任務重試前後執行某些動作,這裏以加日誌爲例
from tenacity import retry, stop_after_attempt, before_log import logging import sys logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) logger = logging.getLogger(__name__) @retry(stop=stop_after_attempt(3), before=before_log(logger=logger, log_level=logging.DEBUG)) def task(): print("task running ... ") raise Exception task()
tenacity重試後的操作類似,如下
from tenacity import retry, stop_after_attempt, after_log import logging import sys logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) logger = logging.getLogger(__name__) @retry(stop=stop_after_attempt(3), after=after_log(logger=logger, log_level=logging.DEBUG)) def task(): print("task running ... ") raise Exception task()
tenacity
Python實用模塊專題
更多有用的python
模塊,請移步
https://xugaoxiang.com/category/python/modules/
參考資料
-
https://github.com/jd/tenacity
http://www.taodudu.cc/news/show-4122770.html?action=onClick