重试retry 重试控制机制
retrying
是一个 Python 包,用于提供一个装饰器(以及一个重试控制机制),允许你将其应用于任何函数或方法上,使得在遇到特定的异常或者返回条件不满足时自动重试。使用 retrying
包中的 retry
函数可以帮助简化代码中处理瞬时错误或不稳定操作(如网络请求)的逻辑。
当你使用 @retry
装饰器装饰一个函数时,可以指定多个参数来控制重试行为,包括:
stop_max_attempt_number
: 重试的最大次数。stop_max_delay
: 最大的重试延迟时间(毫秒),超过这个时间后不再重试。wait_fixed
: 两次重试之间的固定等待时间(毫秒)。wait_random_min
和wait_random_max
: 两次重试之间的随机等待时间的最小值和最大值(毫秒)。retry_on_exception
: 一个函数,当它返回True
时,会在抛出的异常上重试。retry_on_result
: 一个函数,当目标函数返回值使得该函数返回True
时进行重试。
例如,假设你有一个网络请求的函数,由于网络波动,你希望在遇到连接错误时自动重试,但最多重试3次,每次重试之间等待2秒:
from retrying import retry
import requests
@retry(stop_max_attempt_number=3, wait_fixed=2000)
def fetch_data(url):
response = requests.get(url)
response.raise_for_status() # 如果响应码不是 200,会抛出异常
return response.json()
# 使用这个函数,它会在失败时尝试最多3次,每次尝试之间等待2秒
data = fetch_data("https://example.com/api/data")
在这个例子中,如果 requests.get(url)
因为网络问题抛出异常(比如 requests.exceptions.ConnectionError
),fetch_data
函数会自动重试,直到尝试了3次或者成功获取数据为止。
其它
import requests
from retry import retry
from requests.exceptions import RequestException
# 重试最多 3 次,捕获所有与请求相关的异常
@retry(RequestException, tries=3, delay=1, backoff=2, max_delay=3)
def fetch_page(url):
print(f"正在尝试获取页面:{url}")
response = requests.get(url)
response.raise_for_status() # 如果响应码不是 200,会抛出 HTTPError
return response.text
try:
url = "https://example1.com"
page_content = fetch_page(url)
print(page_content)
print("成功获取页面内容")
except RequestException as e:
print(f"请求失败:{e}")
参数解释:
tries
:- 控制最大重试次数。
tries=3
表示最多重试 3 次,包含第一次的尝试。因此,最多会执行 4 次(1 次初始尝试 + 3 次重试)。
- 控制最大重试次数。
delay
:- 控制首次重试的延迟时间(单位:秒)。
delay=1
表示第一次重试时会等待 1 秒钟。 - 如果你设置了
backoff
,第一次重试的时间间隔会根据backoff
参数成倍增加。
- 控制首次重试的延迟时间(单位:秒)。
backoff
:- 控制每次重试的时间间隔增长倍数。
backoff=2
表示每次重试时,重试的时间间隔将是上次间隔的 2 倍(指数增长)。 - 例如,如果第一次重试延迟 1 秒,第二次会延迟 2 秒,第三次会延迟 4 秒(依此类推)。
- 控制每次重试的时间间隔增长倍数。
max_delay
:- 控制重试间隔的最大值。
max_delay=3
表示每次重试的间隔时间不能超过 3 秒。 - 即使根据
backoff
的规则,间隔时间大于 3 秒,系统也会限制为最多 3 秒。
- 控制重试间隔的最大值。
示例:
假设 tries=3
, delay=1
, backoff=2
, max_delay=3
,重试行为如下:
- 第一次尝试:
delay=1
秒(无延迟,直接尝试)。 - 如果第一次失败,第二次尝试会延迟:
delay=1 * backoff = 2
秒。 - 如果第二次失败,第三次尝试会延迟:
delay=2 * backoff = 4
秒,但由于max_delay=3
,会将延迟限制为 3 秒。
示例代码执行流程:
import requests
from retry import retry
from requests.exceptions import RequestException
# 重试最多 3 次,每次重试延迟 1 秒,之后按 2 倍增长,最大间隔为 3 秒
@retry(RequestException, tries=3, delay=1, backoff=2, max_delay=3)
def fetch_page(url):
print(f"正在尝试获取页面:{url}")
response = requests.get(url)
response.raise_for_status() # 如果响应码不是 200,会抛出 HTTPError
return response.text
try:
url = "https://example1.com"
page_content = fetch_page(url)
print(page_content)
print("成功获取页面内容")
except RequestException as e:
print(f"请求失败:{e}")
执行过程:
- 第一次请求,如果失败,等待 1 秒钟后重试。
- 第二次请求,如果失败,等待 2 秒钟后重试。
- 第三次请求,如果失败,等待 3 秒钟后重试(注意:此时会达到最大延迟限制
max_delay=3
,即使根据backoff
应该等待更长时间,也会将其限制为 3 秒)。 - 如果所有尝试都失败,会触发
RequestException
并进入except
语句。
本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18090562