如何让单个Express端点处理并行请求?原因与解决方法
为什么我的Express端点看起来只能串行处理请求?怎么实现并行?
嘿,这个问题其实挺容易踩坑的,我来给你捋清楚~
先搞清楚:你的代码本身是支持并行的!
首先要纠正一个误解:Express本身是基于Node.js的异步非阻塞事件循环模型,默认就支持并行处理请求。你写的sleep函数是用setTimeout实现的异步操作,当第一个请求执行到await sleep(10000)时,Node.js的事件循环会暂时挂起这个请求的回调,转而去处理其他进来的请求——也就是说,第二个请求也会进入await sleep状态,两个请求会同时等待10秒,然后几乎同时返回,而不是第一个等10秒,第二个再等10秒。
那你为什么会觉得它是串行的?大概率是测试方式的问题,常见的坑有:
- 浏览器对同一域名的并发请求有数量限制(比如Chrome默认是6个),如果你发送的请求超过这个数,剩下的会自动排队,看起来像串行;
- 如果你在终端里一行一行敲
curl命令,那请求本身就是串行发送的,自然会串行返回; - 某些测试工具默认是串行发送请求的,没有真正做到并行触发。
怎么验证并行?
你可以用Node.js写个简单的测试脚本,同时发送多个请求,看看实际效果:
const axios = require('axios'); async function runParallelTests() { const requestCount = 5; const promises = []; console.log('开始发送请求:', new Date().toLocaleTimeString()); // 同时创建多个请求Promise for (let i = 0; i < requestCount; i++) { promises.push(axios.get('http://localhost:9999/')); } // 等待所有请求完成 const results = await Promise.all(promises); console.log('所有请求完成:', new Date().toLocaleTimeString()); results.forEach((res, index) => { console.log(`请求${index + 1}返回结果: ${res.data}`); }); } runParallelTests();
运行这个脚本,你会看到所有请求几乎同时启动,10秒后一起完成,这就证明你的Express端点是支持并行的。
如果真的遇到了串行阻塞怎么办?
如果你的实际业务代码里有同步阻塞操作(比如while(true)、同步读取大文件、复杂的同步计算),那才会真的卡住Node.js的事件循环,导致所有请求串行处理。这种情况下的解决办法:
- 把同步阻塞的逻辑放到子进程或者Worker线程中处理,让主事件循环保持空闲,能处理其他请求;
- 尽量使用所有API的异步版本(比如用
fs.promises.readFile代替fs.readFileSync,用异步数据库查询代替同步查询)。
内容的提问来源于stack exchange,提问作者László Monda
相关产品推荐
相关产品推荐

