Node.js学习总结(一)

A,什么是Node.js.
        Node.js是一个可以让javascript运行在服务器端的平台,它可以让javascript脱离浏览器的束缚运行在一般的服务器下面,你可以用Node.js轻松地进行服务器端应用的开发。Node.js是一个为实时Web应用开发而诞生的平台,它充分考虑了在实时响应和超大规模数据下架构的可扩展性,这使得它摒弃了传统的平台依靠多线程来实现高并发的的设计思路,而采用了单线程,异步式I/O和事件驱动的设计模式。这些特性不仅带来了巨大的性能提升,还减少了多线程程序设计的复杂性,从而提高了开发效率。
B,Node.js与javascript的关系.
通常javascript是由ECMAScript,文档对象模型(DOM)和浏览器对象模型(BOM)组成。由于Node.js不运行在浏览器中,所以可以说它只是ECMAScript的一个实现,不包括DOM,BOM等部分。Node.js是一个让javascript运行在浏览器之外的平台,它不运行在浏览器中所以也就不存在浏览器兼容性问题。Node.js的javascript引擎是V8,来自GoogleChrome项目,V8号称是目前世界上最快的javascript引擎。
C,Node.js的特点.
      Node.js作为一个高性能的运行平台,其具有许多优点,比如异步I/O,事件循环机制,单线程和跨平台等。
1)异步I/O:操作系统有同步和并发的概念,设计操作系统就要最求保证任务能够并发执行,于是有了进程和线程等概念。使多个任务并发执行可以提升系统整体的运行速度和充分利用系统资源,从而提高响应时间和吞吐率。线程执行过程中如果遇到磁盘读写或者网络通信(统称为I/O操作),通常是比较耗时的。如果采用的是同步式I/O,一旦遇到I/O操作操作系统就会剥夺这个线程的CPU控制权,使其暂停执行(该线程被阻塞了),同时将资源让给其它的工作线程,当I/O操作完毕时,操作系统再将这个线程的阻塞状态解除回复其对CPU的控制权,令其继续执行;然而如果采用异步式I/O的处理模式将会显著的提高任务的响应时间,当遇到I/O操作时,不会等待I/O操作的完成或数据的返回,而只是将I/O请求发送给操作系统,然后接着执行I/O操作语句的下一条语句(此时没有阻塞,也没有放弃CPU控制权),一旦I/O操作完成,系统会以事件的形式通知执行I/O操作的线程,该线程会在合适的时间处理该事件。下图为同步式和异步式线程的执行过程:
Node.js学习总结(一)

从上图中可以分析出异步式I/O处理可以极大地提高性能。下面我们简单的从用户体验和资源分配两个维度来分析异步I/O的必要性。
(a)用户体验维度:浏览器中javascript和UI渲染在同一单线程模式下执行,这意味着javascript在执行时UI渲染和响应是处于停滞状态的,如果脚本执行时间很长,用户就会明显感觉到页面卡了,以为网页没有响应。而在B/S模型中网络的速度直接影响着网页的实时体验。假如javascript需要获取一个网络资源,如果采用同步方式获取,则javascript需要等待资源完全从服务器端下载下来后才能继续执行,而且这期间UI渲染是停止的,不响应用户的交互操作。这样的处理方式给用户的体验是极差的。但是假如采用异步式I/O,javascript和UI都不会停顿,给用户的感觉就是网页很流畅。
(b)资源分配维度:假如有一组互不相关的任务需要完成,通常有两种处理方式。第一:单线程串行以此执行;第二:多线程并行执行。多线程的代价在于创建线程和执行期间上下文切换的开销较大,另外在复杂的业务中,多线程经常面临锁,状态同步等问题,因此在某些情况下不是最佳选择。单线程顺序执行比较符合我们的顺序思考问题的逻辑,但是串行执行的缺点在于一个执行速度很慢的任务(有大量的I/O操作)会影响后续任务的响应时间,而且在执行I/O操作时,CPU实际上处于空闲等待状态,严重浪费了资源。当然为了节约资源,操作系统会同时启动多个任务,一旦一个任务阻塞便切换到另一个任务。但是对于我们要处理的这一组任务而言,只会创建一个进程(由于是一个整体),而无法分发到多个线程中并发执行,因此串行执行这组任务会浪费资源。因此,单线程同步编程模型会因I/O阻塞导致硬件资源得不到更优的使用;而多线程编程模型也因为编程中的死锁,状态同步等问题带来不便。折衷考虑,利用异步式I/O,避免多线程带来的问题,同时使单线程远离阻塞。
2)事件循环机制:Node.js通过事件循环机制从而实现异步I/O。事件循环就好像是操作系统中的生产者/消费者模型,异步I/O,网络请求等都是事件的生产者,源源不断的为Node.js提供不同类型的事件,这些事件被被传递到相应的观察者(文件I/O观察者,网络I/O观察者等,每个事件对应一个观察者)中,事件循环则从观察者那里取出时间然后处理之(比如调用观察者的回调函数)。在进程启动时Node.js会创建一个类似于while(true)的循环,每次执行循环体的过程就是询问每个观察者是否有事件等待处理,如果有就取出事件和相关的回调函数处理,如果没有事件了就退出进程。事件循环处理流程如下图所示:


3)单线程:在Node.js当中,其实除了javascript是单线程外,Node.js自身是多线程的。当javascript执行中请求I/O操作时便会生成一个请求对象,该请求对象封装着所有的请求状态,包括送入线程池等待执行以及I/O操作完毕后的回调处理等信息。组装好请求对象后便将该对象送入线程池中等待执行。至此javascript调用立即返回,由javascript层面发起的异步调用第一阶段就此结束,javascript线程可以继续执行当前任务的后续操作,当前I/O在线程池中等待执行,其阻塞与否不会影响javascript线程的执行,如此达到异步的目的。当请求对象的I/O操作完成后便会归还线程到线程池中,而且发出I/O执行完成请求。事件循环每次循环过程都会检查线程池中是否有执行完成的请求,如果有就把该请求加入到I/O观察者队列中,然后将其当做事件处理。整个异步I/O流程图如下所示:
Node.js学习总结(一)

从图4可以看出,异步调用中将请求对象放入线程池等待执行后,javascript线程并没有处于等待状态而是继续执行后续任务。这里要理解Node.js的单线程异步I/O的处理模式的机制,同时这也是一种事件驱动的处理模式。
4)跨平台:Node.js基于libuv实现了跨平台,可以直接运行在windows和linux平台下libuv是Node.js上层模块和操作系统之间构建的一层平台层架构。
基于Node.js拥有上述等优点,使其在许多场景中都可以发挥作用。比如Node.js适用于I/O密集型,分布式等应用场景。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值