Node.js 中何时使用同步阻塞代码

When to use synchronous - blocking code in Node.js

我在采访中问过,有没有什么情况会迫使你在node.js服务器中使用阻塞代码?

我的回答是:我在任何项目中都不需要它,但我认为它在某些需要大量 CPU 处理的任务中可能很有用,例如某些图像处理或视频生成。

所以专家,你能帮我纠正一下吗,在任何情况下都必须使用阻止代码吗?

首先,您必须区分不同类型的程序。您希望响应许多不同传入请求的服务器与您编写的用于执行某些文件管理或获取某些内容并将其插入数据库的单个用户程序的需求截然不同。

因此,如果您不是多用户服务器,则可以在任何提供的地方使用同步 I/O(最专门用于文件访问)。例如,我有几个脚本可以在我的硬盘上进行文件管理。这些脚本没有任何服务器组件,并且 运行 在半夜自动 trim 备份,trim 日志文件等...这些脚本完全可以使用同步 I/O 几乎任何东西。

另一方面,如果您是一个多用户服务器并且您需要响应可能随时到达的传入请求,那么您 can/should 只有两次使用阻塞 I/O 或阻塞加密是在启动时或某种关机情况下。对于为传入请求服务的所有其他代码,您必须使用非阻塞、异步 I/O 以避免在请求期间锁定您的服务器并使其无法响应新的传入请求。

如果您有耗时的 CPU 密集型操作,例如图像处理或视频生成,那么您将希望将该处理卸载到另一个线程或进程,这样您的主服务器线程就不会被阻塞那个处理。一种典型的处理方式是创建一个 N processes/threads 的工作池,可以将作业发送到 c运行ch 上。然后,将最 CPU 最密集的工作放在主 nodejs 线程之外,使其能够对传入请求保持响应。

so experts, can you correct that for me, is there any case that a blocking code would be a must?

同步(阻塞)I/O 大大简化了服务器启动,因为您可以同步执行读取配置等操作。您可以异步编写该代码,但是您的模块接口通常最终不得不 return 承诺表明它何时真正准备好并完成初始化,这使模块的使用变得复杂。

例如,require() 是同步的,这确实非常有助于简化初始化。

据我所知,在服务器中可能需要阻塞代码的唯一地方是,当程序已经在退出过程中时,您正试图在程序退出之前向磁盘写入内容。您会收到退出事件的通知,如果您尝试使用异步文件 I/O,那么您的程序将在 I/O 完成之前退出。在这种情况下,您可能需要使用同步文件 I/O(在这种情况下这不是问题)。