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



我在一次采访中问过,是否有任何情况可能会迫使您在node.js服务器中使用阻塞代码

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

所以专家们,你能为我纠正一下吗?有没有任何情况下,阻塞代码是必须的?

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

因此,如果您不是一个多用户服务器,那么您可以在提供的任何位置使用同步I/O(尤其是用于文件访问(。例如,我有几个脚本在我的硬盘上进行文件管理。这些脚本没有任何服务器组件,并且在半夜自动运行以修剪备份、修剪日志文件等。这些脚本完全可以用于任何事情的同步I/O。

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

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

所以专家们,你能纠正我的错误吗?有没有任何情况下,阻塞代码是必须的?

同步(阻塞(I/O极大地简化了服务器启动,因为您可以同步执行读取配置等操作。您可以异步编写该代码,但模块接口最终往往必须返回promise,指示它何时真正准备好并完成初始化,这使模块的使用变得复杂。

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

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

最新更新