gpt4 book ai didi

javascript - Express/Node.js .. 我是否阻塞了事件循环?

转载 作者:搜寻专家 更新时间:2023-10-31 23:50:02 25 4
gpt4 key购买 nike

我在 express 服务器上有一个路由,该路由必须调用一个外部 API,该 API 会发回该服务器上的文件列表。之后您调用它的另一个 API 来获取每个文件的内容。一旦有了它,我就写下内容将每个文件复制到我项目根目录中的一个新文件。

这一切都很好,效果很好。问题是当我与多个用户一起使用时。此请求大约需要 3 分钟才能完成,如果它只是我的应用程序调用该路线的一个实例,那么它每次都可以正常工作。但是如果我打开另一个实例,记录与另一个用户一起并同时启动相同的请求,我遇到了问题。

这不是超时问题,尽管我在处理这个问题时已经处理过这个问题并且已经找到了解决方法。这绝对必须做多个用户同时到达路线。

有时它根本没有完成,有时它会很快为两个用户抛出一个错误,有时只有一个会失败而另一个会完成。

我一直在四处寻找,我怀疑我正在阻塞事件循环,需要使用工作线程之类的东西。我的问题是我在正确的轨道还是我不知道的其他东西?

代码基本上是这样的:

//this whole request takes about 3 minutes to complete if successful due to rate limiting of the external APIs.
//it's hard to imagine why I would want to do this kind of thing, but it's not so important.. what is really important
//is why I get issues with more than 1 user hitting the route.
router.get('/api/myroute', (req, res, next) => {

//contact a remote server's API, it sends back a big list of files.
REMOTE_SERVER.file_list.list(USER_CREDS.id).then(files => {

//we need to get the contents of each specific file, so we do that here.
Promise.all(files.map((item, i) =>
//they have an API for specific files, but you need the list of those files first like we retrieved above.
REMOTE_SERVER.specific_file.get(USER_CREDS.id, {
file: { key: files[i].key }
}).then(asset => {

//write the contents of each file to a directory called "my_files" in the project root.
fs.writeFile('./my_files/' + file.key, file.value, function (err) {
if (err) {
console.log(err);
};
});
})))
.then(() => {
console.log("DONE!!");
res.status(200).send();
})
});
});

最佳答案

您已经达到了 Node 的异步 I/O 的默认限制!长话短说,对于 fs 模块,Node.js 使用了 libuv 线程池,其大小默认为 4。对于某些事情,Node 将其工作委托(delegate)给底层操作系统异步处理程序(epoll、kqueue 等),但对于诸如 DNS、加密或文件系统之类的事情,它使用 libuv。很可能您要写入磁盘的文件数量大于 4。很可能当并行请求进入时它会变得更大。在一天结束时,您只是用完了 libuv 线程,然后 Node 只是有无事可做,但要等到至少有一个线程可以使用。这实际上取决于文件的数量,因此您的应用的行为并不稳定。

您可以做的是,您可以通过传递一个数值大于 4 的环境变量 UV_THREADPOOL_SIZE 来增加线程池的大小。但这仍然非常有限。老实说,Node.js 事件循环模型不是此类事情的最佳选择。还要考虑不同请求写入同名文件的情况。如果您对“最后写入获胜”并发模型没有问题,那么您可能没问题,但您的文件可能会由于错误的操作顺序而最终被损坏。这是一项非常艰巨的任务。

有关 libuv 和那些花哨的线程池的更多详细信息,我建议您观看这个非常好的 talk .

其实Node的官方docsfs 上警告您此类行为。

关于javascript - Express/Node.js .. 我是否阻塞了事件循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55994682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com