项目中使用了第三方服务,和上一篇文章一样:SpringBoot中如何优雅地使用重试https://blog.csdn.net/Xin_101/article/details/134617868
在调用第三方服务时,出现第三方服务连接不到的情况,为了保证服务的相对稳定,
当调用第三方服务出现异常时,进行重试,
本次的项目是Python语言开发的,因此,选择了灵活、功能强大的Tenacity框架。
https://tenacity.readthedocs.io/en/latest/
Tenacity是Python的重试框架,用于简化重试逻辑的编写,
直接在Tenacity中提供的重试方法中配置相关参数即可实现重试功能,
参数化重试机制,如重试次数、时间间隔、重试的异常情况等,
提高开发效率。
通过retry方法实现在指定异常情况下进行重试。
配置重试参数,在需要重试的方法上添加retry注解即可实现重试。
retry源码如下:
tenacity.retry
常用参数解析:
序号 | 参数 | :描述 |
---|---|---|
1 | max_retries | 最大重试次数 |
2 | retry_exception | 触发重试的异常类型 |
3 | reraise | 重新抛出异常开关:true:重新抛出异常;false:不重新抛出异常 |
4 | multiplier | 重试时间倍率,时间间隔:multiplier * 2^(n-1),n为执行次数 |
5 | min_seconds | 最小重试时间间隔 |
6 | max_seconds | 最大重试时间间隔 |
其中,
这里我们对retry方法进行一层包装,有些多余,
先这样写吧,如下:
完成retry方法参数配置后,在需要重试的方法中使用retry框架,
首先初始化retry的方法,
然后在执行的方法上添加注解。
执行结果如下图所示,
按照上面的retry配置,可知min_seconds=4s,max_seconds=10s,max_retries=5,multiplier=1
即重试4次,
"""
重试测试
@author xindaqi
@since 2023-12-02 16:34
"""
from typing import Callable, Any
from datetime import datetime
import logging
from tenacity import (
before_sleep_log,
retry,
retry_if_exception_type,
stop_after_attempt,
wait_exponential,
)
logger = logging.getLogger(__name__)
def retry_decorator(max_retries: int, retry_exception: "RetryBaseT" = retry_if_exception_type(), reraise=True, multiplier=1, min_seconds=4, max_seconds=10) -> Callable[[Any], Any]:
"""重试装饰器
:param max_retries: 最大重试次数
:param retry_exception: 触发重试的异常类型
:param reraise: 重新抛出异常开关:true:重新抛出异常;false:不重新抛出异常
:param multiplier: 重试时间倍率,时间间隔:multiplier * 2^(n-1),n为执行次数
:param min_seconds: 最小重试时间间隔
:param max_seconds: 最大重试时间间隔
:return: 重试对象
"""
return retry(
reraise=reraise,
stop=stop_after_attempt(max_retries),
wait=wait_exponential(multiplier=multiplier, min=min_seconds, max=max_seconds),
retry=retry_exception,
before_sleep=before_sleep_log(logger, logging.WARNING),
)
def function_with_retry(max_retries, retry_exception):
retry_decorator_init = retry_decorator(max_retries, retry_exception)
@retry_decorator_init
def run():
now = datetime.now()
current_time = now.strftime("%Y-%m-%d %H:%M:%S")
print(">>>>>>>>Current time:{}".format(current_time))
a = 1/0
return run()
if __name__ == "__main__":
exception = (
retry_if_exception_type(ZeroDivisionError))
function_with_retry(5, exception)
(1)Tenacity重试框架,提供重试参数配置,简单易用,提高开发效率;
(2)重试参数有max_retries(最大执行次数)、reraise(重新抛出异常标识,如果达到重试次数上限后,是否抛出原生异常给上游调用方),min_seconds最小的时间间隔,即重试的时间间隔最小只能为min_seconds,max_seconds是最大时间间隔,即最大的延迟时间为max_seconds,为重试时间间隔做了限制,保证间隔的合理;
(3)重试时间间隔计算公式为:time_interval=multiplier*2^(n-1),n为重试次数,最终的延迟时间间隔从time_interval、min_seconds和max_seconds中取,计算公式:max(max(0, min_seconds), min(time_interval, max_seconds));
(4)Tenacity可以配置多种异常类型,当出现这些异常时进行重试,细粒度控制重试。