Python3:在访问不可靠服务时的重试策略(持续更新ing...)

诸神缄默不语-个人CSDN博文目录

比较经典的不可靠服务就是访问网络。
最简单的重试策略就是随机time.sleep然后try-catch,这个太基础了我就不写了。本文主要介绍一些比较复杂的策略及其解决方案,比如指数退避及在其基础上衍生出的需求。

最近更新时间:2023.6.2
最早更新时间:2023.6.2

文章目录

  • 1. 基于tenacity库的解决方案
    • 1.1 基础的指数退避策略
    • 1.2 对于不同的异常,想要使用不同退避策略的解决方案
  • 2. backoff库
  • 3. 本文撰写过程中参考的网络资料

1. 基于tenacity库的解决方案

官方GitHub项目:jd/tenacity: Retrying library for Python
官方文档:Tenacity — Tenacity documentation

1.1 基础的指数退避策略

直接用@retry装饰访问不可靠服务的函数就可以。

代码示例:

...
from tenacity import (
    retry,
    stop_after_attempt,
    wait_random_exponential,
)
...
@retry(wait=wait_random_exponential(min=60, max=6000), stop=stop_after_attempt(6))  #60和6000都是秒数,OpenAI官方给的是1和60,是为了OpenAI的API接口速率限制,跟我的场景不一样。这个根据实际情况确定就行
def avoid_proxy_die(response_data:str):
    response1=requests.post(url='https://api.openai.com/v1/chat/completions',
                        headers={'Authorization':f"Bearer {API_KEY}",
                                 'content-type':'application/json'},
                        data=response_data,
                        proxies={"http":"127.0.0.1:7890","https":"127.0.0.1:7890"}
                        )
    return response1

1.2 对于不同的异常,想要使用不同退避策略的解决方案

比较简单的实现方式就是在特定异常上直接增加指定睡眠时间:

@retry(wait=wait_random_exponential(min=20, max=600),stop=stop_after_attempt(6))
def avoid_ChatGPT_die(response_data:str):
    try:
        response1=requests.post(url='https://api.openai.com/v1/chat/completions',
                        headers={'Authorization':f"Bearer {API_KEY}",
                                 'content-type':'application/json'},
                        data=response_data,
                        proxies={"http":"127.0.0.1:7890","https":"127.0.0.1:7890"}
                        )
    except Exception as e:  #这个是代理寄了
        time.sleep(60)
        raise e
    if response1.status_code==200:
        return response1
    else:  #这些情况包括:超过频率限制,秘钥余额用完了,服务器炸了
        raise Exception

ChatGPT给了一个更复杂的解决方案,我没有实现过,也列出来以供参考。
大致逻辑是给函数再包一层用@retry装饰的函数,对不同的异常分别手动调用不同的退避策略:

from tenacity import retry, stop_after_attempt, wait_random_exponential, RetryError
from time import sleep

class SpecifiedException(Exception):
    pass

class OtherException(Exception):
    pass

@retry(stop=stop_after_attempt(3))
def custom_retry(func):
    try:
        func()
    except SpecifiedException:
        sleep(wait_random_exponential(min=1, max=60).next())
        raise RetryError
    except OtherException:
        sleep(wait_random_exponential(min=60, max=6000).next())
        raise RetryError
    except Exception:
        # handle all other exceptions
        pass

def my_func():
    # your code here
    pass

custom_retry(my_func)

2. backoff库

略,待补。

3. 本文撰写过程中参考的网络资料

  1. Rate Limits - OpenAI API:这个是OpenAI官方提供的参考资料,我主要只看了其中tenacity库相关的内容

你可能感兴趣的:(编程学习笔记,python,重试,指数退避,tenacity,backoff)