【发布时间】:2021-10-25 17:03:22
【问题描述】:
我的 Sails js 应用程序具有多租户数据库结构。因此,根据多租户逻辑,我必须在控制器文件中创建一个动态数据库连接。我正在按照这个方法https://sailsjs.com/documentation/reference/waterline-orm/datastores/driver 进行动态 MySQL 数据库连接。
所有 API 都按要求正常工作,但是当我开始对具有 500 个用户和 10 秒加速时间的单个 Api 进行性能测试时,Api 在 300 个请求后开始失败,检查那里的堆栈跟踪低于问题
{
error: Error: Handshake inactivity timeout
at Handshake.<anonymous> (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:160:17)
at Handshake.emit (node:events:369:20)
at Handshake._onTimeout (/usr/src/app/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)
at Timer._onTimeout (/usr/src/app/node_modules/mysql/lib/protocol/Timer.js:32:23)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
--------------------
at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConnection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:116:18)
at Pool.getConnection (/usr/src/app/node_modules/mysql/lib/Pool.js:48:16)
at Object.getConnection (/usr/src/app/node_modules/machinepack-mysql/lib/get-connection.js:78:25)
at wrapper (/usr/src/app/node_modules/@sailshq/lodash/lib/index.js:3282:19)
at Deferred.parley.retry [as _handleExec] (/usr/src/app/node_modules/machine/lib/private/help-build-machine.js:1076:19)
at Deferred.exec (/usr/src/app/node_modules/parley/lib/private/Deferred.js:286:10)
at Deferred.tryCatcher (/usr/src/app/node_modules/bluebird/js/release/util.js:11:23)
at ret (eval at makeNodePromisifiedEval (/usr/src/app/node_modules/bluebird/js/release/promisify.js:184:12), <anonymous>:14:23)
at Deferred.toPromise (/usr/src/app/node_modules/parley/lib/private/Deferred.js:572:19)
at Deferred.then (/usr/src/app/node_modules/parley/lib/private/Deferred.js:431:22) {
code: 'PROTOCOL_SEQUENCE_TIMEOUT',
fatal: true,
timeout: 10000
},
meta: undefined
}
at Object.tenantConnection (/usr/src/app/api/services/utils.js:93:29)
at async Object.login [as user/login] (/usr/src/app/api/controllers/UserController.js:112:28) {
cause: Exception: `getConnection` failed ("failed"). Could not acquire a connection to the database using the specified manager.
Additional data:
{
error: Error: Handshake inactivity timeout
at Handshake.<anonymous> (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:160:17)
at Handshake.emit (node:events:369:20)
at Handshake._onTimeout (/usr/src/app/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)
at Timer._onTimeout (/usr/src/app/node_modules/mysql/lib/protocol/Timer.js:32:23)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
--------------------
at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConnection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:116:18)
at Pool.getConnection (/usr/src/app/node_modules/mysql/lib/Pool.js:48:16)
at Object.getConnection (/usr/src/app/node_modules/machinepack-mysql/lib/get-connection.js:78:25)
at wrapper (/usr/src/app/node_modules/@sailshq/lodash/lib/index.js:3282:19)
at Deferred.parley.retry [as _handleExec] (/usr/src/app/node_modules/machine/lib/private/help-build-machine.js:1076:19)
at Deferred.exec (/usr/src/app/node_modules/parley/lib/private/Deferred.js:286:10)
at Deferred.tryCatcher (/usr/src/app/node_modules/bluebird/js/release/util.js:11:23)
at ret (eval at makeNodePromisifiedEval (/usr/src/app/node_modules/bluebird/js/release/promisify.js:184:12), <anonymous>:14:23)
at Deferred.toPromise (/usr/src/app/node_modules/parley/lib/private/Deferred.js:572:19)
at Deferred.then (/usr/src/app/node_modules/parley/lib/private/Deferred.js:431:22) {
code: 'PROTOCOL_SEQUENCE_TIMEOUT',
fatal: true,
timeout: 10000
},
meta: undefined
}
at Object.tenantConnection (/usr/src/app/api/services/utils.js:93:29)
at async Object.login [as user/login] (/usr/src/app/api/controllers/UserController.js:112:28) {
code: 'failed',
exit: 'failed',
traceRef: {},
raw: [Object]
},
isOperational: true,
code: 'failed',
exit: 'failed',
traceRef: {},
raw: { error: [Error], meta: undefined }
}
注意:我使用的是 Azure Mysql 数据库。
创建和销毁动态连接
// Get the generic, stateless driver for our database (e.g. MySQL).
var Driver = sails.getDatastore().driver;
// Create our own dynamic connection manager (e.g. connection pool)
var manager = (
await Driver.createManager({ connectionString: req.param('connectionUrl') })
).manager;
var db;
try {
db = (
await Driver.getConnection({ manager: managerReport.manager })
).connection;
} catch (err) {
await Driver.destroyManager({ manager: managerReport.manager });
throw err;
}
//**********************************************
// Do some stuff here...
// e.g.
// await Driver.sendNativeQuery({
// connection: db,
// nativeQuery: '...'
// });
//**********************************************
// Finally, before we continue, tear down the dynamic connection manager.
// (this also takes care of releasing the active connection we acquired above)
await Driver.destroyManager({ manager: managerReport.manager });
return res.ok();
【问题讨论】:
标签: mysql node.js azure azure-sql-database sails.js