如何在不使用Node Cluster的情况下实现Express多并发请求处理?
问题描述
我们希望在不使用Node Cluster的情况下处理多并发请求,连续发起3次请求时,它们的执行能几乎同时结束。
示例代码如下:
const execute_select = async () => { const jdbcres = new Driver(Conn.MySQL, {host, port, database}) const d = await jdbcres.sql('SELECT * from db.maindb'); // 执行耗时10秒 } app.post('/select', (request, response) => { execute_select(); response.send('200'); });
当同时发起3次http://localhost/select请求时,出现以下情况:
- 立即收到响应;
- 每个请求都在
const d = await jdbcres.sql('SELECT * from db.maindb')行处阻塞; - 第一个请求10秒完成,第二个接着耗时10秒,第三个同样,总耗时约30秒。
我们想知道是否有办法让/select请求无需等待前一个请求结束,使总耗时控制在10秒左右?
曾尝试将const d = await jdbcres.sql('SELECT * from db.maindb'); // 执行耗时10秒替换为以下代码,但未解决问题:
/* const result = await new Promise((resolve, reject) => { setTimeout(() => { const d = jdbcres.sql('SELECT * from db.maindb') resolve(d); }, 20000); }); */
解决方案
问题核心是你使用的JDBC驱动可能是同步阻塞实现,或者内部用了单连接池/串行执行逻辑,导致数据库查询被串行化,无法真正异步并发。
具体解决方法:
换用异步非阻塞的数据库驱动
确保驱动原生支持异步操作,比如mysql2/promise,它不会阻塞Node.js事件循环,能同时发起多个数据库查询。配置足够连接数的连接池
全局初始化连接池,设置足够的最大连接数(比如10),让每个并发请求能获取独立连接,同时执行查询:const mysql = require('mysql2/promise'); // 全局初始化连接池 const pool = mysql.createPool({ host: '你的主机地址', port: 3306, database: 'maindb', user: '用户名', password: '密码', connectionLimit: 10, // 满足并发需求 queueLimit: 0 }); const execute_select = async () => { // 从连接池取连接执行查询 const [rows] = await pool.query('SELECT * from db.maindb'); // 处理查询结果 }; app.post('/select', async (req, res) => { try { await execute_select(); } catch (err) { console.error('查询失败:', err); } res.send('200'); });避免每次请求新建驱动实例
原代码每次调用execute_select都新建Driver,可能导致资源复用失败或触发驱动内部串行限制,应该全局初始化一次驱动或连接池。
你的尝试无效的原因
用setTimeout包装查询没解决根本问题——如果jdbcres.sql本身是同步阻塞的,即使延迟执行,依然会阻塞事件循环,并发请求还是会被串行处理。
内容的提问来源于stack exchange,提问作者poyango
相关产品推荐
相关产品推荐

