網站首頁 編程語言 正文
1、前言
在我們日常的開發工作中,為了代碼的健壯性,我們通常會對方法中的業務代碼進行try-except的包裝,以防止在發生異常的時候進程被中斷。如果發生異常,我們該怎么辦呢?有同學可能用自己的方式(循環)去做了重試,那么有沒有一種通用的可靠的重試方式呢?答案是有的,它就是retrying庫,今天我們就一起來看看。
2、快速開始
retrying是一個極簡的使用Python編寫的,擁有1.8k??的可以實現方法異常重試的庫,我們在實際使用中直接為我們的方法增加一個@retry的裝飾器即可。
2.1、安裝retrying
pip install retrying
2.2、模擬無限重試
假設我們現在有一個方法demo1,這個方法中調用了另一個接口e1,但是被調用的這個e1接口不穩定,當e1接口返回異常的時候,我們需要去重試。
from retrying import retry import time ? # 一個會返回異常的接口e1 def e1(): ? ?time.sleep(1) ? ?print('err') ? ?# 我們拋出異常模擬接口異常 ? ?raise TypeError ? # 全局計數器 a=1 @retry def demo1(n): ? ?# 方法中調用全局變量,需要global ? ?global a ? ?# 進行try-except ? ?try: ? ? ? ?print(f'開始嘗試!{a}') ? ? ? ?a+=1 ? ? ? ?e1() ? ?except Exception as e: ? ? ? ?print(e) ? ? ? ?# 當重試完成后還未成功,則返回超時 ? ? ? ?raise TimeoutError if __name__=='__main__': ? ?demo1(0)
代碼執行結果:
你會發現,我們代碼會一值被重試,這是為什么呢?
默認的retry裝飾器就是無限重試的,直到重試成功為止。因為我們的接口e1是永遠返回異常的,所以這個重試將會永遠持續下去。
我們改造e1方法如下,即可在重試第10次成功:
# 一個會返回異常的接口e1 def e1(): ? ?time.sleep(1) ? ?print('err') ? ?# 當重試次數達到10時,返回True ? ?if a>=10: ? ? ? ?print('ok!') ? ? ? ?return True ? ?# 我們拋出異常模擬接口異常 ? ?raise TypeError
代碼執行結果:
開始嘗試!1
err
開始嘗試!2
err
開始嘗試!3
err
開始嘗試!4
err
開始嘗試!5
err
開始嘗試!6
err
開始嘗試!7
err
開始嘗試!8
err
開始嘗試!9
err
ok!
2.3、模擬最大重試次數
上面的無限重試明顯在實際業務場景中適用面不是非常廣,當我們需要使用重試次數來限制時,我們就可以使用retry的裝飾器參數stop_max_attempt_number
來實現。
# 全局計數器 a=1 @retry(stop_max_attempt_number=3) def demo1(n): ? ?# 方法中調用全局變量,需要global ? ?global a ? ?# 進行try-except ? ?try: ? ? ? ?print(f'開始嘗試!{a}') ? ? ? ?a+=1 ? ? ? ?e1() ? ?except Exception as e: ? ? ? ?print(e) ? ? ? ?# 當重試完成后還未成功,則返回超時 ? ? ? ?raise TimeoutError
以上代碼表示,我們只重試3次,如果還未成功,則返回超時異常。
代碼執行結果:
2.4、模擬最大重試時間
除了可以使用重試次數限制外,當我們對時間要求比較明確的時候,我們就可以使用stop_max_delay
參數來指定最大重試時間。這個參數的單位是ms。
# 全局計數器 a=1 @retry(stop_max_delay=2000) def demo1(n): ? ?# 方法中調用全局變量,需要global ? ?global a ? ?# 進行try-except ? ?try: ? ? ? ?print(f'開始嘗試!{a}') ? ? ? ?a+=1 ? ? ? ?e1() ? ?except Exception as e: ? ? ? ?print(e) ? ? ? ?# 當重試完成后還未成功,則返回超時 ? ? ? ?raise TimeoutError
如上代碼表示,當重試時間超過2s就會拋出超時異常。因為在e1方法中,每次調用都會休眠1s,所以對于限制兩秒,我們只能在2s內重試2次。
代碼執行結果:
2.5、模擬重試間隔時間
當我們不希望重試間隔時間太長的時候,我們可以使用參數wait_fixed
指定重試的間隔時間。
# 全局計數器 a=1 @retry(stop_max_delay=6000,wait_fixed=1000) def demo1(n): ? ?# 方法中調用全局變量,需要global ? ?global a ? ?# 進行try-except ? ?try: ? ? ? ?print(f'開始嘗試!{a}') ? ? ? ?a+=1 ? ? ? ?e1() ? ?except Exception as e: ? ? ? ?print(e) ? ? ? ?# 當重試完成后還未成功,則返回超時 ? ? ? ?raise TimeoutError
如上代碼表示最大重試時間6秒,重試間隔1秒,但是e1方法中還休眠了1秒,所以在6秒內,我們理論上只能重試4次(不是3次)。
代碼運行結果:
在此基礎上,retrying還為我們提供了隨機的重試間隔時間參數。
- wait_random_min,重試間隔最小時間
- wait_random_max,重試間隔最大時間
一般,這兩個參數都是成對出現,用于限制重試間隔時間的范圍。
2.6、指定重試調用的方法
retrying允許我們在重試的同時去調用一個方法。使用參數stop_func
來指定這個方法名。
# attempts, delay這兩個參數是必填的 def stop_f(attempts, delay): ? ?print('發生異常了,正在進行重試!') # 全局計數器 a=1 @retry(stop_func=stop_f,stop_max_delay=3) def demo1(n): ? ?# 方法中調用全局變量,需要global ? ?global a ? ?# 進行try-except ? ?try: ? ? ? ?print(f'開始嘗試!{a}') ? ? ? ?a+=1 ? ? ? ?e1() ? ?except Exception as e: ? ? ? ?print(e) ? ? ? ?# 當重試完成后還未成功,則返回超時 ? ? ? ?raise TimeoutError
代碼運行結果:
但是stop_func存在一個問題就是和stop_max_delay、stop_max_attempt_number結合使用的時候,后面兩者會失效。
2.7、指定重試的異常類型
當我們需要針對特定的異常才進行重試時,就需要用到這個參數:retry_on_exception
。
2.8、指定重試的特定條件
當達到某個條件才會進行重試,需要使用參數:retry_on_result
。
原文鏈接:https://juejin.cn/post/7108202816665026573
相關推薦
- 2022-12-12 C語言實現循環打印星號圖形再鏤空_C 語言
- 2023-07-09 css樣式重疊解決辦法
- 2022-09-08 Python中LSTM回歸神經網絡時間序列預測詳情_python
- 2022-12-08 C#?如何調用C++?dll?string類型返回_C#教程
- 2022-09-09 使用Dockerfile腳本定制鏡像的方法_docker
- 2022-12-08 oracle自動生成uuid的實現方法_oracle
- 2022-05-10 oracle如何創建或刪除臨時表空間和空間詳解
- 2022-07-09 Python如何通過變量ID得到變量的值_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支