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

Lambda查询RDS数据库时表现不稳定问题求助

Lambda调用RDS Proxy时响应不稳定问题

测试代码时,Lambda有时无任何响应,有时可正常执行查询并返回数据,表现极不稳定,且无报错信息。已使用RDS Proxy,也未触发任何报错,怀疑问题与async/await的使用有关,代码如下:

async function RDSToken() {

   
  var signer =  new AWS.RDS.Signer({
    region: 'us-east-1', 
    hostname: 'proxy',
    port: 3306,
    username: 'username' 
  });

var host ='proxy'
var user ='username'
var db ='name'

let token =  signer.getAuthToken({username: 'admin' });
let connectionConfig = {
    host: host, 
    user: user,
    database: db, 
    ssl: { rejectUnauthorized: false},
    password: token,
    authSwitchHandler: function ({pluginName, pluginData}, cb) {
        console.log("Setting new auth handler.");
    }
  };
connectionConfig.authSwitchHandler = (data, cb) => {
  if (data.pluginName === 'mysql_clear_password') {
      let password = token + '\0';
      let buffer = Buffer.from(password);
      cb(null, password);
  }};


  try {
      connection =  await mysql2.createConnection(connectionConfig);
  } catch(err) {
      console.error('error connecting to the database');
      console.error(err);
      var response = {  
          statusCode: 500,
          "headers": {
              "Content-Type": "application/json"
          },
          body: 'error connecting to the database' +err
      };
      return response;
  }

return connection

}
async function randomfact() {
  
  var connection = await RDSToken();
  
  let sql = 'SELECT * FROM quote_header;';
  return await new Promise((resolve, reject) => {
     connection.query(sql, (err, result) => {
      if (err) {
        reject(err);
      }
      else {
        resolve(result);
      }
    });
  });
}
async function Dashboard() {
    
  const result = await randomfact();
  console.log(result)

}

问题排查与修复

核心问题点

  1. 异步操作未等待:signer.getAuthToken()是异步方法,直接赋值给token会得到一个未resolved的Promise,用它作为密码会导致认证流程随机失败,引发无响应。
  2. 连接泄漏:每次调用RDSToken都会创建新连接,但使用后未关闭,Lambda复用执行环境时会耗尽连接资源,导致后续请求无响应。
  3. 全局变量污染:connection未用let/const声明,成为全局变量,在Lambda复用环境中会导致连接混乱。
  4. 认证逻辑不完整:authSwitchHandler只处理了mysql_clear_password插件,未处理其他情况,可能导致认证卡住无报错。

修复后的代码

const AWS = require('aws-sdk');
const mysql2 = require('mysql2/promise'); // 使用Promise版mysql2,避免手动封装

async function getRDSToken() {
  const signer = new AWS.RDS.Signer({
    region: 'us-east-1',
    hostname: 'proxy',
    port: 3306,
    username: 'username'
  });

  // 必须await获取token,确保拿到有效字符串
  const token = await signer.getAuthToken({ username: 'admin' });
  
  const connectionConfig = {
    host: 'proxy',
    user: 'username',
    database: 'name',
    ssl: { rejectUnauthorized: false },
    password: token,
    authSwitchHandler: (data, cb) => {
      if (data.pluginName === 'mysql_clear_password') {
        const password = token + '\0';
        cb(null, password);
      } else {
        // 处理未知认证插件,避免无响应
        cb(new Error(`不支持的认证插件: ${data.pluginName}`));
      }
    }
  };

  try {
    const connection = await mysql2.createConnection(connectionConfig);
    return connection;
  } catch (err) {
    console.error('数据库连接错误:', err);
    return {
      statusCode: 500,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ error: '数据库连接失败', details: err.message })
    };
  }
}

async function getRandomFact() {
  const connection = await getRDSToken();
  
  // 检查是否是连接错误响应
  if (connection.statusCode) {
    return connection;
  }

  try {
    // 使用execute方法(Promise版)替代回调式query
    const [rows] = await connection.execute('SELECT * FROM quote_header;');
    return rows;
  } catch (err) {
    console.error('查询错误:', err);
    return {
      statusCode: 500,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ error: '查询失败', details: err.message })
    };
  } finally {
    // 无论成功失败,都关闭连接,避免泄漏
    await connection.end();
  }
}

async function Dashboard() {
  const result = await getRandomFact();
  console.log(result);
}

额外优化建议

  • 使用RDS Proxy时,建议用createPool创建连接池,复用连接减少开销,避免频繁创建销毁连接。
  • 给数据库操作添加超时配置,比如在connectionConfig中设置timeout: 10000,防止无响应挂起。
  • Lambda中避免全局创建资源,每次请求都通过连接池获取/释放连接,适配执行环境复用机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:31:00