You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何程序化检测AWS Serverless v2 Aurora MySQL是否缩至0 ACU?

解决方案:检测Aurora Serverless v2 0 ACU状态及冷启动重试

一、程序化检测0 ACU状态

要直接判断Aurora Serverless v2集群是否缩至0 ACU,可通过AWS SDK调用RDS的describeDBClusters接口,获取集群运行状态与容量信息:

  1. 依赖与权限配置:确保应用或Lambda已引入AWS SDK for JavaScript(推荐v3版本),并为执行角色添加rds:DescribeDBClusters权限。
  2. 检测逻辑示例:
import { RDSClient, DescribeDBClustersCommand } from "@aws-sdk/client-rds";

const rdsClient = new RDSClient({ region: process.env.AWS_REGION });

async function isClusterPaused(clusterIdentifier) {
  try {
    const command = new DescribeDBClustersCommand({
      DBClusterIdentifier: clusterIdentifier
    });
    const response = await rdsClient.send(command);
    
    // 集群缩至0 ACU时,状态为"paused"且Capacity字段为0
    const cluster = response.DBClusters[0];
    return cluster.Status === "paused" || cluster.Capacity === 0;
  } catch (err) {
    console.error("检测集群状态失败:", err);
    return false;
  }
}

调用该函数即可判断集群是否处于0 ACU的暂停状态。

二、处理冷启动失败的重试机制

现有代码存在回调与async/await混用、无重试逻辑的问题,导致冷启动时无有效响应。以下是优化后的代码,加入状态检测与重试逻辑:

优化后代码

const mysql = require('mysql2/promise'); // 改用promise版本适配async/await
import { RDSClient, DescribeDBClustersCommand } from "@aws-sdk/client-rds";

const rdsClient = new RDSClient({ region: process.env.AWS_REGION });
const CLUSTER_ID = process.env.CLUSTER_IDENTIFIER;
const RETRY_MAX = 3; // 最大重试次数
const RETRY_DELAY = 10000; // 重试间隔(10秒,预留集群扩容时间)

// 检测集群是否暂停
async function isClusterPaused() {
  try {
    const command = new DescribeDBClustersCommand({ DBClusterIdentifier: CLUSTER_ID });
    const response = await rdsClient.send(command);
    const cluster = response.DBClusters[0];
    return cluster.Status === "paused" || cluster.Capacity === 0;
  } catch (err) {
    console.error("检测集群状态出错:", err);
    return false;
  }
}

// 使用连接池管理数据库连接(替代单次连接)
const pool = mysql.createPool({
  host: process.env.hostname,
  port: process.env.portslot,
  user: process.env.username,
  password: process.env.userpassword,
  database: 'databaseOne',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// 带重试的查询函数
async function queryWithRetry(sql, retryCount = 0) {
  try {
    // 检测到集群暂停时,等待后重试
    if (await isClusterPaused()) {
      console.log("集群处于暂停状态,等待扩容...");
      await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
      return queryWithRetry(sql, retryCount + 1);
    }

    const [results] = await pool.query(sql);
    return results;
  } catch (err) {
    // 未达最大重试次数时递归重试
    if (retryCount < RETRY_MAX) {
      console.log(`查询失败,第${retryCount+1}次重试...`, err.message);
      await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
      return queryWithRetry(sql, retryCount + 1);
    }
    throw new Error(`查询失败,已达最大重试次数: ${err.message}`);
  }
}

exports.getRecords = async (event) => {
  try {
    const sql = 'SELECT * FROM tableOne';
    const results = await queryWithRetry(sql);
    console.log("查询成功:", results);
    return {
      statusCode: 200,
      body: JSON.stringify(results)
    };
  } catch (err) {
    console.error("API处理失败:", err);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: err.message })
    };
  }
};

关键优化点

  • 改用mysql2/promise模块,避免回调与async/await混用的逻辑混乱
  • 使用连接池管理连接,提升复用性与性能
  • 添加基于集群状态的重试逻辑,给冷启动集群预留扩容时间
  • 完善错误捕获与返回,避免无响应情况

三、额外建议

  • 调整暂停阈值:若API调用频率低,可延长「闲置后暂停」的时间,减少冷启动触发次数
  • Lambda预热:通过CloudWatch定时触发Lambda,提前唤醒数据库,避免用户请求遭遇冷启动
  • 监控告警:通过CloudWatch监控ServerlessDatabaseCapacity指标,当容量为0时触发告警,辅助排查问题

内容的提问来源于stack exchange,提问作者LWSChad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:30:49