如何在 RDS 上正确使用 Knex / Bookshelf 和 MySQL
Posted
技术标签:
【中文标题】如何在 RDS 上正确使用 Knex / Bookshelf 和 MySQL【英文标题】:How to properly use Knex / Bookshelf with MySQL on RDS 【发布时间】:2020-03-15 02:25:55 【问题描述】:我有一个Node.js
应用程序,在AWS RDS
上使用mysql
和Bookshelf
和Knex
库。 RDS 实例有一个max_connections
值90
。
我使用以下作为连接对象。
knex:
client: 'mysql',
connection:
host: 'xxxxxxx.rds.amazonaws.com',
user: 'xxx',
password: 'xxxxx',
database: 'xxxx',
charset: 'utf8'
,
debug: true,
pool:
min: 2,
max: 20
,
acquireConnectionTimeout: 10000
,
const config = require('./environment');
const knex = require('knex')(config.knex);
module.exports = require('bookshelf')(knex).plugin('registry');
'use strict';
const bookshelf = require('../config/bookshelf');
const config = require('../config/environment');
module.exports = bookshelf.model(`TableA`,
tableName: 'TableA'
, );
我的应用程序收到了许多请求,有时会因以下错误而崩溃。
未处理的拒绝 TimeoutError: Knex: Timeout getting a 联系。游泳池可能已经满了。你错过了一个 .transacting(trx) 调用?
和
错误:ER_CON_COUNT_ERROR:连接太多
我还看到服务器 PROCESSLIST
中有许多连接(平均为 40 到 50 个),Command
为 sleep
。
我怀疑这些错误发生在服务器上的所有90
连接已完全使用/knex 尝试从池中获取新连接时。什么可能是解决此问题的永久解决方案,以及处理此类应用程序的最佳实践。
【问题讨论】:
可能值得提供有关创建和使用数据库连接的代码摘录。 更新了@RichChurcher,如果这是你的意思。谢谢 还有一个请求/查询超时的示例? 看起来每次您需要../config/bookshelf
时都会创建新的 knex
实例
您可以(并且应该)验证 RDS 最大连接限制是否生效。只需使用标准 RDS 监控并关注 DB Connections
指标。另外,您是否在 AWS Lambda 上运行您的应用程序?这很容易让您同时运行数十个 lambda 调用,每个调用都打开与 RDS 的连接。
【参考方案1】:
我不认为是 RDS max_connections
导致了问题,假设您在任何时候都只有一个上述应用程序代码的实例在运行。
您的应用程序使用数据库连接池,最多可容纳 20 个连接。如果所有这些连接都在使用中,那么在连接超时之前,应用程序最多会等待acquireConnectionTimeout
ms,即10000
。
所以我怀疑您的应用程序由于负载而需要处理大量数据库查询,或者有一些慢速查询占用连接。这会导致等待最终超时的连接的查询积压。调查可能的情况并更新我们。
您可以同时尝试的事情。
增加acquireConnectionTimeout
。
增加连接池大小。
如果是由慢查询引起的,请在尝试上述方法之前对其进行优化。
记录慢速查询的可能方法:
在 RDS 上启用慢查询日志。 Knex query 事件记录事务持续时间(假设您正在使用事务)。【讨论】:
【参考方案2】:当客户端完成 MySQL 后,让它断开连接。
另外,检查wait_timeout
的值。降低它会强制断开连接,而不是“休眠”直到你回来。
【讨论】:
以上是关于如何在 RDS 上正确使用 Knex / Bookshelf 和 MySQL的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Knex.js 中正确设置“updatedAt”时间戳?