【问题标题】:Response Order in Node.js?Node.js 中的响应顺序?
【发布时间】:2016-04-08 08:28:18
【问题描述】:

我浏览了一些关于 Node.js 和 Event Loop 的介绍性文章,但有一点不清楚 - 如果有多个并发请求,那么响应是否总是按照发出请求的顺序排列?假设如果 20 个请求同时完成,那么第 20 个响应是否必须等待其他 19 个被清除(响应回客户端)?

更新:我想知道这是否类似于多个 setTimeouts 排队的方式?

【问题讨论】:

    标签: node.js concurrency


    【解决方案1】:

    node.js 作为单线程运行 Javascript。因此,在任何给定时间,只有一段 Javascript 正在运行。

    但是,几乎所有 I/O(例如网络、文件访问等)都是异步且非阻塞的。因此,如果在很短的时间内向您的服务器发出 20 个请求,到达服务器的第一个请求将开始执行它的请求处理程序,其他请求将排队。但是,一旦第一个请求遇到异步操作(例如从本地文件系统读取),该请求将在发生非阻塞异步 I/O 时暂停,并且行中的下一个请求将开始运行.

    然后,第二个请求将一直运行,直到它完成或直到它也遇到一个异步 I/O。当第二个请求在异步 I/O 上等待时,另一个请求将开始运行。系统调度程序将确定下一个操作是完成第一个请求的异步 I/O 请求,还是启动队列中等待的第三个请求。

    各种请求将继续以这种方式进行,直到全部完成。多个请求可能同时“进行中”(意味着它们已经开始,但尚未完成),但在任何给定时刻只有一个实际执行代码。

    这有时被称为合作任务。不同请求之间没有抢先式多任务处理,每个请求都会自动获取主机 CPU 的时间片。但是,只要一个请求遇到异步 I/O 操作,就会告诉调度程序等待运行的其他请求可以运行。

    这一切都由 node.js 中的事件队列管理。一段 Javascript 一直运行直到完成。如果它发出一个异步 I/O 请求然后完成,那么另一段也在等待运行的 Javascript 可以开始运行。完成后,JS 引擎将下一项从事件队列中拉出并运行。这可能是一个新的传入请求,也可能是对某个其他请求的某个异步 I/O 操作的完成。

    这种系统的优点是:

    1. 它的可伸缩性非常好,尤其是对于 I/O 绑定的服务器操作,因为您可以只使用一个 Javascript 线程同时“进行中”许多请求。协作任务非常轻量和快速。

    2. 编写这样的系统需要注意的“竞争条件”要少得多,因为实际上没有两段 Javascript 会同时运行。这意味着您可以经常在请求之间共享状态,而无需使用互斥锁(就像在多线程环境中一样)。由于线程安全的错误通常很难避免和测试,因此消除这些类型的错误是一个主要优势。

    3. 协作模型在概念上很简单,更易于学习和安全编程。

    这种系统的缺点是:

    1. 它不会在受 CPU 限制的任务之间共享 CPU。具有大量 CPU 密集型计算的 node.js 程序员通常必须使用集群或子进程来处理繁重的 CPU 计算,以免使主请求处理 Javascript 线程的工作负担过重,并使其过于无响应.

    2. 需要进程集群以最大限度地利用多个处理器,然后必须在这些进程之间共享任何共享数据。人们经常使用 Redis 等内存数据库在进程之间共享数据。

    3. 你不能随便启动另一个 Javascript 线程来做某事。

    【讨论】:

    • 很棒的答案。您能否添加更多关于被视为异步的进程和不被视为异步的进程的详细信息。
    • @GandalftheWhite - 在 node.js 中,几乎所有在回调函数中传递其结果的库函数都是异步的。例如fs.readFile() 是异步的。 fs.readFileSync() 是同步的。根据函数的接口或文档,这通常是显而易见的,但为了正确使用函数,您必须了解这一点。
    • @GandalftheWhite - 异步操作必须基于在本机代码中异步执行的底层操作,因为您无法在 node.js 中从头开始编写真正的异步操作。您必须要么基于现有的异步操作,要么必须创建一个本机代码插件以异步方式实现操作,然后稍后使用结果调用回调。
    • @jfriend00 有点困惑。所以如果 3 个响应完成了它们的异步活动并同时返回到服务器/事件循环,它们是按顺序选择的吗?被挑选出来并返回给客户的三个中的最后一个有一些等待时间?
    • @Kodathon - 是的。它是一个事件队列。轮到他们时,每次从队列中挑选一个项目。 node.js 一次只运行一段 Javascript,所以如果一个正在运行,那么其他人会在事件队列中等待,直到轮到他们。
    猜你喜欢
    • 1970-01-01
    • 2013-03-05
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多