在 AWS CLI 调用上出现 Throttling Exception 作为 ThrottlingException 错误

use*_*927 4 python throttling amazon-web-services aws-cli boto3

我试图通过 AWS CLI 探索一项名为 Workspaces 的新 AWS 服务,它似乎能够满足每秒 1 个请求。当我尝试同时多次点击时,它会抛出ThrottlingException错误。由于工作空间尚未包含在boto包中,因此我通过子进程调用在 python 中使用 CLI。

    def describe_workspaces():
        process=subprocess.Popen(access_endpoint.split(), stdout=subprocess.PIPE)
        output=process.communicate()[0]
Run Code Online (Sandbox Code Playgroud)

因此,如果我调用此函数 >=1/sec,则会出现 ThrottlingException。怎么处理呢?并且会有多个用户同时调用该函数。

我正在考虑进行批处理和异步调用,但如何适应这种架构?

abd*_*wer 9

新解决方案:

您可以使用 fromprovided by 来解决此问题Configbotocore.configBoto3是一个AWS SDKin Python,通过指定重试配置,如代码片段中所示:

import boto3 
from botocore.config import Config

config=Config(connect_timeout=5, read_timeout=60, retries={'max_attempts': 5})

def describe_workspaces():
    return boto3.client('workspaces', config).describe_workspaces()
Run Code Online (Sandbox Code Playgroud)

参考:


旧的解决方案:

您可以使用in来解决此问题Boto3,方法是添加异常处理并重试,如下代码片段所示:AWS SDKPythonThrottlingException

import boto3
from botocore.exceptions import ClientError

def describe_workspaces(tries=1):
    try:
        return boto3.client('workspaces').describe_workspaces()
    except ClientError as exception_obj:
        if exception_obj.response['Error']['Code'] == 'ThrottlingException':
            if tries <= 3:
                print("Throttling Exception Occured.")
                print("Retrying.....")
                print("Attempt No.: " + str(tries))
                time.sleep(3*tries)
                return describe_workspaces(tries + 1)
            else:
                print("Attempted 3 Times But No Success.")
                print("Raising Exception.....")
                raise
        else:
            raise
Run Code Online (Sandbox Code Playgroud)

您可以创建一个AWS client外部函数并可以根据需要修改逻辑。

您也可以处理ThrottlingExceptionvia ,但如果您编写一些脚本而不是脚本,则会更有意义。对于,推荐。AWS CLIBash/ShellPythonPythonBoto3

有关更多详细信息,请查看以下内容:AWS Workspaces API


通用旧解决方案:

如果您的代码有多个(多个)AWS client调用,并且您不想ThrottlingException为每个调用添加相同的代码来一次又一次地处理和重试,以实现可重用性(DRY;不要重复自己)并避免不必要的代码重复,您可以使用以下代码片段:

import time
import boto3
from botocore.exceptions import ClientError

def generic_aws_client_method(client, method_name, method_arguments, tries=1):
    """Generic AWS client method with throttling exception handling"""
    try:
        client_method = getattr(client, method_name)
        return client_method(**method_arguments)
    except ClientError as exception_obj:
        if exception_obj.response['Error']['Code'] == 'ThrottlingException':
            if tries <= 3:
                print("Throttling Exception Occured.")
                print("Retrying.....")
                print("Attempt No.: " + str(tries))
                time.sleep(3*tries)
                return generic_aws_client_method(
                    client,
                    method_name,
                    method_arguments,
                    tries + 1
                )
            else:
                print("Attempted 3 Times But No Success.")
                print("Raising Exception.....")
                raise
        else:
            raise
Run Code Online (Sandbox Code Playgroud)

您可以在下面找到一些有关如何使用它的示例:

# AWS clients for AWS S3 and AWS SSM respectively
s3_client = boto3.client('s3')
ssm_client = boto3.client('ssm')

# Example 1: With multiple method arguments
mapping = {'Name': '/prod/aws-eks-vpc-id', 'WithDecryption': True}
returned_object = generic_aws_client_method(ssm_client, "get_parameter", mapping)
print(returned_object)

# Example 2: With single method argument
mapping = {'operation_name': 'describe_parameters'}
returned_object = generic_aws_client_method(ssm_client, "get_paginator", mapping)
print(returned_object)

# Example 3: With no method argument
mapping = {}
returned_object = generic_aws_client_method(s3_client, "list_buckets", mapping)
print(returned_object)
Run Code Online (Sandbox Code Playgroud)

测试 ThrottlingException 处理:

为了测试ThrottlingException上述代码片段中的处理,请使用以下代码片段自行引发ClientError自定义:

raise ClientError(
    {'Error': {'Code': 'ThrottlingException', 'Message': 'Rate exceeded'}},
    'generic_aws_client_method'
)
Run Code Online (Sandbox Code Playgroud)