Node.js系列——(4)优点及场景

背景

以前几篇系列文章简单介绍了node.js的安装配置及基本操做:

Node.js系列——(1)安装配置与基本使用
Node.js系列——(2)发起get/post请求
Node.js系列——(3)链接DBnode

接下来,咱们就来总体认识下node.js数据库

node.js

node.js官网对它的介绍是这样的:api

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 浏览器

V8引擎

V8使用C++开发,并在谷歌浏览器中使用。在运行JavaScript以前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),而且使用了如内联缓存(inline caching)等方法来提升性能。缓存

有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。markdown

具体内容可参考:为何V8引擎这么快?异步

这里写图片描述

事件驱动

传统技术实现下,当一个请求到达时,会分配一个线程,该线程会占用内存,当请求的任务作完时,线程才会退出并释放内存。但node.js只有一个单线程,全部的链接都由这一个线程来处理。函数

网上流传着一个生动的例子:oop

传统技术下的处理方式——>餐馆里一个服务员接待一桌客人,服务这一桌客人点餐、上菜、陪侍,到客人离开;
node.js的处理方式——>餐馆里只有一个服务员,当有客人来,他就去招待点餐,点餐结束后就去处理其余事情,能够去招待其余客人,也能够去上菜。post

Node.js是单进程单线程的,那他是如何作到高性能的呢?
主要经过事件驱动和异步回调。node中几乎全部的事件机制都是使用观察者模式实现的。

说到观察者模式,就要先明确主题Subject(即被观察者)和观察者Observer。

以下图所示,在node中事件扮演者Subject的角色,而这个事件上的处理函数就是观察者。还拿上面的餐馆服务员的例子来讲,客人进入餐馆这一动做就是一个事件,当这一事件触发时,他的观察者就会进行一系列操做(好比招待入座、点餐等)。
这里写图片描述

因为node是单线程的,所以在实际场景中会有不少事件堆积到一块儿,这也就是事件队列。

这里写图片描述

在上图中所示:
1) 若是有任务或请求到达,会被放入右侧的Event Queue(事件队列)中。事件队列中每一个任务会存放两个东西,处理方法和回调方法,即function和callback。

2)事件循环Event Loop会根据事件队列中的任务列表进行执行,这时分两种状况:

  • 若是取到的任务是non-Blocking非阻塞的,那么能够直接执行而后调用他相对应的回调函数。
  • 若是任务是Blocking阻塞的(如IO操做等),就不会直接执行,而是从线程池Thread Pool中取出一个线程来执行,当该线程完成后,就会调用回调函数,接下来的操做跟上一种状况同样了。到最后该线程的任务执行完毕,那么线程所占用的资源被释放。

Tips:
当执行过程当中遇到I/O阻塞(读取文件、查询数据库、请求套接字、访问远程服务等)时,事件循环线程不会停下等待结果,转而继续执行队列中的下一个任务,不会在事件循环线程中执行。在函数执行时,Node.js在事件队列中放置回调函数,它的顺序根据函数的完成快慢决定。

具体内容参考:Node.js的事件驱动模型

Rest API

Rest API 这部分就不用多说了,node采用这种方式来规范接口和数据的形式,用法也很简单。

场景

前面说了这么多node.js的优势,那是否是任何场景都优先选择他呢?确定不是的,咱们来看下他的缺点。

一、node.js不适合作CPU密集型的工做
咱们不能说node.js彻底是单线程的,由于当遇到阻塞式的任务时,他会交给其余线程去处理。但除此以外,node是单线程的。所以,若是是CPU密集的场景下,选择使用node,没法使他的优点发挥出来。

二、大量的计算可能会使node单线程暂时失去反应

三、若是有一个Exception影响到了node的核心事件循环,那么整个实例就会崩溃。

相关文章
相关标签/搜索