nodejs第一天

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.javascript

  咱们来到Node的官方网站的时候就能看到这么一句话,这句话体现了node的几大特色,咱们来一一细看。前端

1、 Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

  咱们学习一个东西,首先咱们要知道这东西是用来干什么的。之前我据说node的时候觉得nodejs是一个框架,当了解到node以后就认为这只是在服务端的javascript,可是事实的真相是这样的么?咱们来看一看上面这段话。Node.js是一个构建在Chrome的V8引擎上的javascript的运行时,可能你不太能理解运行时是什么,其实在个人理解中就和Java的JRE(Java Runtime Environment)是差很少的,他提供了API环境、运行环境,让咱们的js在服务端能够跑起来,同时提供了能够对文件系统、网络等等进行操做的api,这是让前端工程师无比兴奋的突破。java

2、 Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.

  接下来的这句话体现了Node的几大特性:node

  • 事件驱动
  • 非阻塞I/O模型
  • 单线程(里面没提,可是我以为这也是一大特性)

  再说上面的几个特性以前,咱们先来看一看,在我学习的途中常常会看到有人说Node在处理高并发、I/O密集型服务是具备优点的,那么个人疑问是I/O密集型是啥,搜索资料后发现,跟I/O密集相对应的是CPU密集,咱们能够看一看这二者之间的区别。web

  • I/O密集:若是一个程序大部分消耗的时间都是用来对文件的I/O操做,数据库的操做,或者是网络操做,存取这一类的操做,那么咱们就能够说这是I/O密集型的服务。
  • CPU密集: 若是一个程序的时间都消耗在计算,解压,压缩等等须要CPU来进行操做的话,那么咱们就能够说这是一个CPU密集型的服务。

  好了咱们看完这二者之间的区别,咱们也就能了解,为啥Node适合web开发,你想想咱们在进行web开发的时候,咱们进行的都是些什么操做,静态资源读取、网络操做、数据库的增删改查,咱们能够发现web场景中I/O操做是最耗时的操做。如今CPU的提速咱们执行指令的速度是很快的,可是咱们进行I/O操做仍是很是耗时的。咱们能够看到web是一个很典型的I/O密集型服务,那么咱们为何说Node就很是适合web场景呢?咱们等会儿再谈。ajax

  下面咱们来看一看高并发的状况,在《深刻浅出NodeJS》这本书中咱们能看到朴灵老师对服务模型的看法,我以为很能说明问题,咱们一块儿来看一看:数据库

  1. 石器时代:同步
      在好久好久之前,咱们服务器是同步的,一次只能服务一个请求,就好比说咱们一个饭店,请了一个厨子一个服务员,咱们如今只有一个厨子,因此咱们如今只能接收一个客人的点餐,等上个客人的作好了咱们才能继续进行下面一位客人的点餐,咱们都知道这样的效率确定是不行的,因此又有了下面的演进。api

  2. 青铜时代:复制进程
      咱们能够经过进程的复制,一个进程服务一个请求,这样咱们就可以服务多个请求了,可是梦想是很美好的,理想很丰满。继续用上面的例子,咱们饭店大起来了,一个厨子这样已经忙不过来了,这时候,咱们能想到的是什么,再多请几个厨子,这样也可以解决多个客人的问题,可是咱们想了一下,请这么多厨子,工资谁发啊,太贵了。这也是复制进程的一个缺点,进程的复制是很是昂贵的,咱们要复制进程内的状态,并且进程内还会有不少相同的状态会形成浪费,那么又该怎么办呢?服务器

  3. 白银时代:多线程
      咱们从上面的角度上来想,咱们速度慢的操做也就是读取的操做,不须要很厉害的厨子,小厨子就好了,因而乎咱们就炒掉了大厨,用大厨的钱请了几个小厨子,这样咱们的小厨子也可以进行炒菜,因此咱们接到点餐以后,就给这几个小厨子作。可是呢咱们一个服务员对应的厨子是有限的,咱们能够想象,点菜这个操做是很是快的,可能服务员点完菜以后就开始玩了,等厨子作好了才会端上来,这就形成了CPU的浪费,同时呢,对于多线程来讲,占用内存空间,线程的上下文切换等等问题也是没法作到很好的知足需求。网络

  4. 黄金时代:事件驱动
      为了解决高并发问题,基于事件驱动的服务模型就出现了,就像Node和Nginx都是基于事件驱动的,采用单线程就避免了没必要要的内存开销和上下文切换。看上面的例子,其实咱们雇一个服务员,排队叫号,而后就接待下一个客人,不用等这个客人的菜好了才服务下一个,等厨子作好了菜就直接给服务员说菜作好了,而后叫号,客人来取就OK了。

单线程

  借用一张老师的图,其实这张图其实咱们能看得很清楚,咱们JS是单线程的,node中也是这样的,客户端的N个请求,咱们接收到以后,是直接将耗时得操做放到了后面的线程池里去操做,使用单线程能够避免内存的消耗,以及上下文的切换。同时,咱们利用事件驱动,能够在后面的线程I/O操做完成后以事件的方式通知主线程,而后返回结果。
  其实说到这里,有些人就和我同样困惑了,不是说nodejs是单线程么,怎么又冒出了多线程。其实咱们想想也可以明白,若是nodejs只是靠单线程工做,那么他怎么完成高并发的web服务呢?咱们能够这么说,nodejs的单线程是针对主进程的,而异步操做、I/O操做等等都是靠操做系统底层的多线程调度了,nodejs的单线程只是负责调度,就像饭店的服务员同样,只负责接单,作菜的都是后台的厨师。还有就是nodejs是单线程,那么如今的多核CPU该怎么去使用呢?其实不用咱们担忧,node是考虑了这样的状况的,nodejs是有专门的模块来进行操做的。

事件驱动

  那么事件驱动又是个什么东西呢?其实,咱们在作前端开发的时候是常常和事件打交道的,好比ajax,咱们发起一个请求,而后监听事件,成功以后就执行回调。其实这也是node的一大特色,就像node在接收请求同样的,node接收到请求以后,将对应的I/O操做交给操做系统,而后监听事件,当I/O操做完成以后,触发事件执行回调拿到数据。

非阻塞I/O

  阻塞I/O就是当用户发一个读取文件的操做的时候,进程就会被阻塞,直到要读取的数据所有准备好返回给用户。那非阻塞I/O呢,就是用户发起一个读取文件操做的时,函数当即返回,不做任何等待,进程继续执行,当读取操做完成以后,主进程再去拿数据。那程序如何知道要读取的数据已经准备好了呢?最简单的方法就是轮询,这个在朴灵老师的书里面也提到了几种方式。


  今天就简单的学习了一下node,若是有什么地方不对的请多指教,也是才学习nodejs。

相关文章
相关标签/搜索