在使用Express和OracleDB nodejs模块开发的用于Oracle数据库的Rest API的负载测试过程中,我面临性能问题。我看到在负载测试期间,在每秒向开发的API请求的数量增加的过程中,性能下降。这个问题在对数据库的存储过程和标准选择请求中重现。从数据库端,我看到了每个请求的标准且稳定的响应时间。数据库在启动请求的同时接收请求。从应用程序(响应(端来看,它看起来像是将响应放入某种队列中,并由包中的nodejs(OracleDB模块(读取。每个请求的标准响应时间为0.5秒,每秒10个请求时,我可能会收到3-5秒的响应时间。
这个问题会在不同的连接池大小上重现(比每秒的请求数更大(。目前,我被可能导致这个问题的各种选择所困扰。这种行为的原因可能是什么?或者nodejs的oracleDB模块有哪些诊断或转向选项?
下面的一些代码:
creating the connection:
const init = async () => {
try {
Logger.info(`oracle instant client address ${process.env.LD_LIBRARY_PATH}`);
const pool = await oracledb.createPool(dbCredentials);
Logger.info('db connections pool created');
return pool;
} catch (err) {
Logger.error(`init() error: ${err.message}`);
}
};
let pool = await init();
路线:
router.get('/test', async (req, res, next) => {
try {
const result = await testController(pool);
sendResponse(res, 200, result);
} catch (e) {
sendErrResponse(res, 500, e.message);
}
});
控制器:
const testController = async (pool) => {
let connection;
try {
connection = await pool.getConnection();
} catch (error) {
return error;
}
try {
let items = { items: [{ itemSKU: 'xxxxx', itemQTY: 1234 }, { itemSKU: 'yyyyy', itemQTY: 123}] };
items = JSON.stringify(items);
const { rows: data } = await connection.execute(
'select shop_id, prod_id, qnt from TABLE(pkg_ecom.check(:items))',
{ items },
);
return data;
} catch (error) {
return error;
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
};
缩放节点oracledb连接负载的常见问题是node.js线程饥饿。在应用程序启动之前,增加环境变量UV_THREADPOOL_SIZE的值。请参阅文档"连接、线程和并行性"。在Linux上,package.json
文件可能有:
"scripts": {
"start": "export UV_THREADPOOL_SIZE=10 && node index.js"
},
. . .
您可以通过在创建池期间设置enableStatistics
属性,然后调用pool.getStatistics((或pool.logStatistics(来监控池的使用情况,请参阅连接池监控。请注意排队的getConnection()
请求是否过多。
您还应该阅读节点oracledb案例研究"始终使用连接池"以及"如何使用"。