浅析Node处理CPU密集型任务的方法

Node处理CPU密集型任务的方法有哪些?下面本篇文章就来带大家了解一下Node处理CPU密集型任务的方法,希望对大家有所帮助!

浅析Node处理CPU密集型任务的方法

node.js极速入门课程:进入学习

我们日常工作中或多或少听说过以下的话:

Node是一个非阻塞I/O(non-blocking I/O)和事件驱动(event-driven)的JavaScript运行环境(runtime),所以它非常适合用来构建I/O密集型应用,例如Web服务等。

不知道当你听到类似的话时会不会有和我一样的疑惑:单线程的Node为什么适合用来开发I/O密集型应用?按道理来说不是那些支持多线程的语言(例如Java和Golang)做这些工作更加有优势吗?

要搞明白上面的问题,我们需要知道Node的单线程指的是什么。【相关教程推荐:nodejs视频教程】

Node不是单线程的

其实我们说Node是单线程的,说的只是我们的JavaScript代码是在同一个线程(我们可以叫它主线程)里面运行的,而不是说Node只有一个线程在工作。实际上Node底层会使用libuv的多线程能力将一部分工作(基本都是I/O相关操作)放在一些主线程之外的线程里面执行,当这些任务完成后再以回调函数的方式将结果返回到主线程的JavaScript执行环境。可以看看示意图:

浅析Node处理CPU密集型任务的方法

注: 上图是Node事件循环(Event Loop)的简化版,实际上完整的事件循环会有更多的阶段例如timers等。

Node适合做I/O密集型应用

从上面的分析中我们知道Node会将所有的I/O操作通过libuv的多线程能力分散到不同的线程里面执行,其余的操作都放在主线程里面执行。那么为什么这种做法就比Java或者Golang等其它语言更适合做I/O密集型应用呢?我们以开发Web服务为例,Java和Golang等主流后端编程语言的并发模型是基于线程(Thread-Based)的,这也就意味他们对于每一个网络请求都会创建一个单独的线程来处理。可是对于Web应用来说,主要还是对数据库的增删改查,或者请求其它外部服务等网络I/O操作,而这些操作最后都是交给操作系统的系统调用来处理的(无需应用线程参与),并且十分缓慢(相对于CPU时钟周期来说),因此被创建出来的线程大多数时间是无事可做的而且我们的服务还要承担额外的线程切换开销。和这些语言不一样的是Node没有为每个请求都创建一个线程,所有请求的处理都发生在主线程中,因此没有了线程切换的开销,并且它还会通过线程池的形式异步处理这些I/O操作,然后通过事件的形式告诉主线程结果从而避免阻塞主线程的执行,因此它理论上是更高效的。这里值得注意的是我只是说Node理论上是更快的,实际上真不一定。这是因为现实中一个服务的性能会受到很多方面的影响,我们这里只是考虑了并发模型这一个因素,而其它因素例如运行时消耗也会影响到服务的性能,举个例子,JavaScript是动态语言,数据的类型需要在运行时进行推断,而GolangJava都是静态语言它们的数据类型在编译时就可以确定,所以它们实际执行起来可能会更快,占用内存也会更少。

Node不适合做CPU密集型任务

郑重声明:本文版权包含图片归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们(delete@yzlfxy.com)修改或删除,多谢。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

留言与评论(共有 0 条评论)
昵称:
匿名发表
   
验证码: