【问题标题】:Will Node.js get blocked when processing large file uploads?Node.js 在处理大文件上传时会被阻塞吗?
【发布时间】:2014-04-10 21:02:30
【问题描述】:

Node.js 在处理大文件上传时会被阻塞吗?

由于 Node.js 只有一个线程,是不是在上传大文件时所有其他请求都会被阻塞?

如果是这样,我应该如何处理 nodejs 中的文件上传?

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    所有 I/O 操作都由 Node.js 处理,内部使用多个线程;它是单线程、基于事件和异步的 I/O 功能的编程接口。

    因此,您的示例的大上传是由 Node.js 管理的单独线程执行的,当该线程完成其工作时,您的回调将被放入事件循环队列中。

    当您执行 CPU 密集型任务时,它会阻塞。假设我们有一个任务 compute() 需要几乎连续运行,并进行一些 CPU 密集型计算。


    回答主要问题“我应该如何处理 nodejs 中的文件上传?
    检查您在服务器上保存文件的代码(或库),它是否依赖于 writefile()writeFileSync()?
    如果它使用writefile(),那么它是异步的;但如果是writeFileSync(),它是同步版本。


    更新:回应评论:

    “答案“不,它不会阻塞”是正确的,但解释是 完全错误。 JS 在一个线程中,I/O 在一个线程中(相同) 线。事件循环/异步处理/回调使这成为可能。不需要多个线程。 " - andrey-sidorov

    没有用于文件操作的异步 API,因此 Node.js 使用线程池。你可以在libuv的代码中看到。你可以在lib/fs.js 中查看 fs.readFile 的源代码,你会看到 binding.read。每当您在 Node 的核心模块中看到绑定时,您就是在寻找进入 C++ 领域的门户。使用 NODE_SET_METHOD(target, "read", Read) 可以使用此绑定。如果你知道任何 C 语言,你可能会认为这是一个宏——它最初是,但现在它是一个函数。

    回到Read 中的ASYNC_CALL,其中一个参数是read系统调用读取。但是等等,这个功能不会阻塞吗?

    是的,但这不是故事的结局。 Introduction to libuv 表示以下内容:

    "libuv文件系统操作不同于socket操作。socket操作使用操作系统提供的非阻塞操作。文件系统操作在内部使用阻塞函数,但是在线程池中调用这些函数并且当需要应用交互时通知注册到事件循环的观察者。"

    总结: Node API 方法writeFile() 是异步的,但这并不一定意味着它在下面是非阻塞的。正如 libuv book 指出的那样,套接字(网络)代码是非阻塞的,但文件系统更复杂。有些事情是基于事件的(kqueue),有些事情使用线程池(如本例)。

    考虑通过C code on which Node.js is developed了解更多信息:

    【讨论】:

    • “不,它不会阻塞”的答案是正确的,但解释是完全错误的。 JS 在一个线程中,而 I/O 在一个(相同的)线程中。事件循环/异步处理/回调使这成为可能。不需要多个线程。
    • @nilveryboring 很高兴它有帮助
    • @Andrey Sidorov 感谢您的评论,这让我的解释超出了要求.. :)
    • 您对 linux 下的文件操作是正确的,但原始帖子指的是文件上传(客户端通过 http / tcp 发送大量数据)。在这种情况下,我可能会将这些数据直接流式传输到 S3 或数据库,不需要 fie IO
    • @Amol 对我的评论语气感到抱歉,但令我感到奇怪的是,这么多人将节点并发解释为“JS 在一个线程中,但有用于 IO 的线程池”,因为这是非常错误的和误导性的解释
    【解决方案2】:

    这取决于用于完成该任务的功能。如果您使用的是异步函数,那么 Node.js 将不会阻塞。但也有同步函数,例如fs.readFileSync (FileSystem Doc),会阻塞执行。

    请注意并选择异步函数。这样 Node.js 将在外部库完成慢速任务/等待时继续运行。一旦这些任务完成,事件循环将处理结果并执行您的回调。

    您可以在此处阅读有关事件循环的更多信息:Understanding the Node.js event loop

    【讨论】:

      【解决方案3】:

      这就是 node.js 异步的确切原因。

      node.js 中的大多数(全部?)函数涉及输入/输出操作(瓶颈是 CPU 或 RAM 以外的其他设备)操作发生在单独的线程上,让您的 node.js 服务器在等待时执行一些其他代码.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-11
        • 2017-07-26
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2022-01-06
        • 2023-03-26
        • 1970-01-01
        相关资源
        最近更新 更多