首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AWS Aurora Serverless -通信链路故障

AWS Aurora Serverless -通信链路故障
EN

Stack Overflow用户
提问于 2019-10-01 21:53:18
回答 3查看 7K关注 0票数 8

我在我的python代码中使用了MySQL Aurora集群(启用了Data ),并且我得到了一个communications link failure异常。这通常发生在集群已经休眠了一段时间的时候。

但是,一旦集群处于活动状态,我就不会出错。我每次都要发送3-4个请求才能正常工作。

例外细节:

上一次成功发送到服务器的数据包是0毫秒前。驱动程序尚未收到来自服务器的任何数据包。调用BadRequestException操作时发生错误( ExecuteStatement ):通信链接失败

我怎样才能解决这个问题?我正在使用标准的boto3库

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-10-10 23:49:06

这是AWS高级商业支持公司的回复。

代码语言:javascript
复制
Summary: It is an expected behavior

详细答覆:

我可以看到,当您的Aurora实例处于非活动状态时,您会收到此错误,并且一旦您的实例处于活动状态并接受连接,您将停止接收它。请注意,这是一个预期的行为。一般来说,Aurora的工作方式与Aurora中提供的Aurora不同,而集群处于“休眠状态”--它没有分配给它的计算资源,也没有一个db。接收到连接,将分配计算资源。由于这种行为,您将不得不“唤醒”集群,第一个连接可能需要几分钟才能像您所看到的那样成功。

为了避免这种情况,您可以考虑增加客户端的超时。此外,如果启用了暂停,可以考虑禁用暂停2。禁用暂停后,还可以将最小Aurora容量单元调整为更高的值,以确保群集始终有足够的计算资源来服务新连接3。请注意,调整最小ACU可能会增加服务4的成本。

还请注意,Aurora Serverless仅推荐用于某些工作负载5。如果您的工作负载高度可预测,并且您的应用程序需要定期访问DB,我建议您使用提供的Aurora集群/实例来确保您的业务的高可用性。

2 Aurora的工作原理- Aurora的自动暂停和恢复- https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.how-it-works.html#aurora-serverless.how-it-works.pause-resume

3设置Aurora集群- https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.setting-capacity.html的容量

4 Aurora Serverless无服务器价格https://aws.amazon.com/rds/aurora/serverless/

5使用Aurora用例- https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.html#aurora-serverless.use-cases

票数 10
EN

Stack Overflow用户

发布于 2020-08-18 17:36:23

如果它对某人有用,这就是我如何在醒来时管理重试的方法。

客户端返回一个BadRequestException,因此即使您更改了客户端的配置,boto3也不会重试,请参见https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html

我的第一个选择是尝试使用Waiters,但是RDSData没有任何服务员,然后我尝试创建一个带有错误匹配器的自定义服务生,但是只尝试匹配错误代码,忽略消息,而且由于BadRequestException也可以由一个sql语句中的错误引发,所以我也需要验证消息,所以我使用了一种BadRequestException函数:

代码语言:javascript
复制
def _wait_for_serverless():
    delay = 5
    max_attempts = 10

    attempt = 0
    while attempt < max_attempts:
        attempt += 1

        try:
            rds_data.execute_statement(
                database=DB_NAME,
                resourceArn=CLUSTER_ARN,
                secretArn=SECRET_ARN,
                sql_statement='SELECT * FROM dummy'
            )
            return
        except ClientError as ce:
            error_code = ce.response.get("Error").get('Code')
            error_msg = ce.response.get("Error").get('Message')

            # Aurora serverless is waking up
            if error_code == 'BadRequestException' and 'Communications link failure' in error_msg:
                logger.info('Sleeping ' + str(delay) + ' secs, waiting RDS connection')
                time.sleep(delay)
            else:
                raise ce

    raise Exception('Waited for RDS Data but still getting error')

我用这样的方式:

代码语言:javascript
复制
def begin_rds_transaction():
    _wait_for_serverless()

    return rds_data.begin_transaction(
        database=DB_NAME,
        resourceArn=CLUSTER_ARN,
        secretArn=SECRET_ARN
    )
票数 7
EN

Stack Overflow用户

发布于 2022-02-07 11:46:57

我也得到了这个问题,并从Arless使用的解决方案和与Jimbo的对话中获得了灵感,并提出了以下解决办法。

我定义了一个装饰器,它重试无服务器的RDS请求,直到可配置重试持续时间过期为止。

代码语言:javascript
复制
import logging
import functools
from sqlalchemy import exc
import time

logger = logging.getLogger()


def retry_if_db_inactive(max_attempts, initial_interval, backoff_rate):
    """
    Retry the function if the serverless DB is still in the process of 'waking up'.
    The configration retries follows the same concepts as AWS Step Function retries.
    :param max_attempts: The maximum number of retry attempts
    :param initial_interval: The initial duration to wait (in seconds) when the first 'Communications link failure' error is encountered
    :param backoff_rate: The factor to use to multiply the previous interval duration, for the next interval
    :return:
    """

    def decorate_retry_if_db_inactive(func):

        @functools.wraps(func)
        def wrapper_retry_if_inactive(*args, **kwargs):
            interval_secs = initial_interval
            attempt = 0
            while attempt < max_attempts:
                attempt += 1
                try:
                    return func(*args, **kwargs)

                except exc.StatementError as err:
                    if hasattr(err.orig, 'response'):
                        error_code = err.orig.response["Error"]['Code']
                        error_msg = err.orig.response["Error"]['Message']

                        # Aurora serverless is waking up
                        if error_code == 'BadRequestException' and 'Communications link failure' in error_msg:
                            logger.info('Sleeping for ' + str(interval_secs) + ' secs, awaiting RDS connection')
                            time.sleep(interval_secs)
                            interval_secs = interval_secs * backoff_rate
                        else:
                            raise err
                    else:
                        raise err

            raise Exception('Waited for RDS Data but still getting error')

        return wrapper_retry_if_inactive

    return decorate_retry_if_db_inactive

然后可以使用这样的方法:

代码语言:javascript
复制
@retry_if_db_inactive(max_attempts=4, initial_interval=10, backoff_rate=2)
def insert_alert_to_db(sqs_alert):
    with db_session_scope() as session:
        # your db code
        session.add(sqs_alert)

    return None

请注意,我正在使用sqlalchemy,因此代码需要调整以适应特定的目的,但希望能作为启动程序使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58192747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档