我有一些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做类似的事情?
任何帮助将不胜感激!
答案 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)