2

我将 Lambda 与 RDS 代理一起使用,以便能够重用与 MySQL 数据库的数据库连接。

我应该在执行查询后关闭连接还是将其保持打开状态以供 RDS 代理处理?

如果我应该关闭连接,那么首先使用 RDS 代理有什么意义呢?

这是我的 lambda 函数的示例:

const mysql = require("mysql2/promise")

exports.handler = async (event, context) => {

  const connection = mysql.createConnection({
    host: process.env.RDS_HOST, // RDS Proxy endpoint here
    user: process.env.RDS_USER,
    database: process.env.RDS_DATABASE,
    password: process.env.RDS_PASSWORD,
    ssl: "Amazon RDS"
  })

  try {
    await connection.connect()
    console.log(`Connected to db. ConnectionId: ${connection.threadId}`)
  } catch (err) {
    return handleError(err)
  }

  try {
    // Do some queries
  } catch (err) {
    return handleError(err)
  } finally {
    await connection.end() // Should I close the connection here?
  }

  return response(200, "Success")
}

编辑:请注意,在处理程序(全局范围)之外初始化连接将使 lambda 函数在同一执行环境中的调用之间保留连接变量的值,这将导致以下错误连接时无法添加新命令在短时间内多次调用lambda函数时处于关闭状态,因为连接在第一次调用时已经关闭,所以我最好建议在处理程序内部而不是外部定义连接。

4

1 回答 1

4

TDLR:总是关闭数据库连接

RDS 代理位于您的应用程序和数据库之间,除了使用代理端点之外,不应导致任何应用程序更改。


我应该在执行查询后关闭连接还是将其保持打开状态以供 RDS 代理处理?

无论您使用或不使用数据库代理,都不应让数据库连接保持打开状态。

连接是一种有限且相对昂贵的资源。

经验法则是尽可能晚地打开连接并尽快关闭数据库连接。未明确关闭的连接可能不会添加或返回到池中。关闭数据库连接是一个很好的数据库客户端。

将数据库资源与许多打开的连接捆绑在一起,您会发现自己需要更多的 vCPU 用于您的数据库实例,这会导致 RDS 代理价格标签更高。


如果我应该关闭连接,那么首先使用 RDS 代理有什么意义呢?

关键是您的 Amazon RDS 代理实例为您维护一个与您的 RDS 数据库实例建立连接的池 - 它位于的应用程序和您的 RDS 数据库之间。

代理不负责关闭您建立的本地连接,也不应该负责。

它负责通过为需要它的应用程序自动管理连接多路复用/池和共享来提供帮助。

AWS 文档中明确提到了需要它的应用程序示例:

许多应用程序,包括那些建立在现代无服务器架构上的应用程序,可能有大量与数据库服务器的开放连接,并且可能以高速率打开和关闭数据库连接,从而耗尽数据库内存和计算资源。


为避免任何疑问,您还可以随时查看 AWS 提供的关闭连接的示例链接到来自docs ),或 AWS Compute Blog 中另一个示例。

于 2021-12-11T17:21:03.870 回答