NodeJs多线程、多进程、定时任务

JavaScript017

NodeJs多线程、多进程、定时任务,第1张

JS是单线程语言,减少了线程间切换的开销,且不用考虑锁的问题,因此适合IO密集型项目。

JS的单线程,其实指的是js主引擎线程的。除此之外还有定时器线程、异步http线程(ajax)等,最终通过Event Loop协调执行。

为了充分利用多核CPU,可以使用 worker_threads 实现多线程, child_process 或 cluster 实现多进程(master-worker模式)。

不同于浏览器中的 web worker ,nodejs中通过 worker_threads 实现多线程。通常在计算密集型场景中,才需要使用NodeJs多线程,因此使用场景较少。

electron中即经常使用该模块。

cluster 封装了 child_process.fork ,并内置了负载均衡,可有效实现多进程。

Node.js 是如何工作的?

Node.js 的主要思路是:使用非阻塞的,事件驱动的 I/O 操作来保持在处理跨平台 (across distributed devices) 数据密集型实时应用时的轻巧高效。这听起来有点绕口。

它的真正含义是,Node.js 不是一个即将主导Web开发的世界的银弹级的平台。相反,它是一个满足特别需求的平台。你肯定不会希望使用 Node.js 去做 CPU密集型操作。事实上,使用它进行繁重的计算等于摒弃 Node 几乎所有的优点。Node 真正的亮点在于建设高性能,高扩展性的互联网应用——因为它能够处理庞大的并且高吞吐量的并发连接。

它的工作原理是相当有趣的。传统的网络服务技术,是每个新增一个连接(请求)便生成一个新的线程,这个新的线程会占用系统内存,最终会占掉所有的可用内存。而 Node.js 仅仅只运行在一个单线程中,使用非阻塞的异步 I/O 调用,所有连接都由该线程处理,在 libuv 的加分下,可以允许其支持数万并发连接(全部挂在该线程的事件循环中)。

做一个简单的计算: 假设是普通的Web程序,新接入一个连接会占用 2M 的内存,在有 8GB RAM的系统上运行时, 算上线程之间上下文切换的成本,并发连接的最大理论值则为 4000 个。这是在传统 Web服务端技术下的处理情况。而 Node.js 则达到了约 1M 一个并发连接的拓展级别 (相关证明).

当然,在所有客户端的请求共享单一线程时也会有问题, 这也是一个编写 Node.js 应用的潜在缺陷. 首先, 大量的计算可能会使得 Node 的单线程暂时失去反应, 并导致所有的其他客户端的请求一直阻塞, 直到计算结束才恢复正常。 其次,开发人员需要非常小心,不要让一个 Exception 阻塞核心的事件循环,因为这将导致 Node.js 实例的终止(实际上就是程序崩溃)。( 笔者注:如 PHP 中某个页面挂掉是不会影响网站运行的,但是 Nodejs 是一个线程一个线程来处理所有的链接,所以不论是计算卡了或者是被异常阻塞了都可能会影响到其他所有的链接。解决方案在稍后讨论。)

说node.js单线程,是说你写的程序不能建立新的线程,v8引擎、openssl之类的里面应该是有线程的吧。

node.js的程序是分成一个个tick按顺序执行,每个tick都是一组function。process.nextTick就是把一个function加入的下一个tick里面,这样就可以让它不卡在这一个tick。