Node.js 接口响应太慢,怎么优化?

心霞 Dev 阅读 15

我用 Express 写了个 API,请求一多就卡得不行,本地测试都慢到离谱。

试过加 cluster 模块启动多进程,但 CPU 占用飙到 100%,响应时间反而更长了。数据库查的是 MongoDB,单条查询其实不慢,但并发一上来就堵住了。

这是我的路由处理代码:

app.get('/api/data', async (req, res) => {
  const result = await db.collection('items').find({}).toArray();
  res.json(result);
});

是不是哪里写得不对?有没有办法在不换框架的前提下提升吞吐量?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
FSD-永伟
看了你的代码,问题应该出在 find({}).toArray() 这一行。

你这代码是典型的"一次性把数据全捞出来"的写法。数据量小的时候没感觉,一旦 items 集合有几万条文档,每次请求都要把全部数据加载到内存再序列化成 JSON 返回,Node.js 单线程直接被阻塞,事件循环卡死,后续请求全排队等着。

而且你加了 cluster 反而更慢,说明问题不在 CPU 计算能力,而是每个进程都在抢内存和数据库连接,越搞越乱。

几个改法,按优先级来:

第一,加分页,别一次全查。

app.get('/api/data', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const pageSize = parseInt(req.query.pageSize) || 20;
const skip = (page - 1) * pageSize;

const [items, total] = await Promise.all([
db.collection('items').find({}).skip(skip).limit(pageSize).toArray(),
db.collection('items').countDocuments({})
]);

res.json({ items, total, page, pageSize });
});


第二,只查需要的字段,别把整个文档都返回。

db.collection('items').find({}, { projection: { name: 1, status: 1, createdAt: 1 } }).skip(skip).limit(pageSize).toArray();


第三,给常用查询条件加索引。如果你有筛选条件比如 status,在 MongoDB 里执行:

db.items.createIndex({ status: 1 });


第四,如果数据真的要全量返回(比如导出功能),用游标流式处理,别用 toArray()

app.get('/api/export', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.write('[');

const cursor = db.collection('items').find({});
let first = true;

cursor.forEach(doc => {
if (!first) res.write(',');
res.write(JSON.stringify(doc));
first = false;
}).then(() => {
res.write(']');
res.end();
});
});


另外,cluster 模块先撤掉,你这是 I/O 密集型瓶颈,开多进程只会增加上下文切换开销,不会解决问题。先把查询优化好,吞吐量能翻好几倍。
点赞 1
2026-03-01 15:35