需要建议在python中添加AWS API中的exponenital回退逻辑

时间:2017-02-26 01:42:14

标签: python api amazon-web-services elastic-beanstalk

我有一些lambda函数正在用python编写多个AWS Elastic beanstalk API调用。它工作正常。但是自从最近几天我们得到了限制错误。在与AWS讨论后,他们告诉他们在代码中添加指数退避逻辑。因此,如果它是节流阀,将在增量间隔重试相同的API调用。我得到了他们所说的以及它是如何工作的,但我不明白如何添加我的代码。他们有CLI文档,但他们没有API,如下所示http://docs.aws.amazon.com/general/latest/gr/api-retries.html

有人可以给我一个简单的例子我们如何映射API调用的响应并重试如果它像我在我的代码中使用的一个api调用一样,如下所示

import boto3

conn = boto3.client('elasticbeanstalk')

response = conn.describe_environments(EnvironmentNames=["xyz"])

return response

我知道简单的方法,如果条件,通过检查响应是“速率超过”使用虽然我认为我可以实现这一点。但我想检查一下CLI的示例,我该如何为API做类似的事情?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

您可以使用proxy object来包装任何AWS客户端对象,并向代理对象添加一些retrying logic

from botocore.exceptions import ClientError
import retrying
import wrapt

class RetriedClient(wrapt.ObjectProxy):
"""Add retry logic to a boto3 client.

Wait 2^x * 1000 milliseconds between each retry, up to 10 seconds,
then 10 seconds afterwards.

"""

    def is_throttling_error(exception):
        """Botocore throws just a generic ClientError exception."""
        return isinstance(exception, ClientError) \
            and "RequestLimitExceeded" in exception.response

    @retrying.retry(
        wait_exponential_multiplier=1000,
        wait_exponential_max=10000, 
        retry_on_exception=is_throttling_error)
    def __getattr__(self, name):
        return getattr(self.__wrapped__, name)


# Create a boto3 client to Cloudformation
cf_client = boto3.client('cloudformation')

# Add exponential backoff retries to all client methods
wrapped_cf_client = RetriedClient(cf_client)

然后你可以像通常使用boto3的内置客户端一样使用wrapped_cf_client

resp = wrapped_cf_client.describe_stacks()

DEPRECATION NOTE:

在较新版本的botocore中,有一种更好的方法来配置boto3 SDK的重试逻辑。这适用于从1.6.0的版本botocore开始:

from botocore.config import Config

config = Config(
    retries = dict(
        max_attempts = 10
    )
)

ec2 = boto3.client('ec2', config=config)