《Node.js》之事件处理机制以及事件环机制(二)

传统服务器与Node.js的比较编程

    传统的服务器在面临高并发的场景时,会使用多线程方案,服务器会为客户端的请求分配一个线程,使用同步的I/O,系统经过线程切换来弥补同步I/O调用过程当中的时间开销。Apache就是使用的这种方式,因为I/O操做会消耗比较多的时间,经过多线程的方式解决高并发的问题,难以实现高性能,可是能够实现很复杂的逻辑。     可是大多数网站的服务端不须要太多的计算处理,收到请求以后交给其余的服务进行处理,将处理结果返回给客户端。所以Node.js会针对这样的应用场景使用单线程模型进行处理,并不会为每个客户端的请求建立一个线程,而是经过一个线程处理全部的请求,而后对I/O操做进行异步处理,这样的方式能够减小建立、销毁线程以及线程切换消耗的时间。安全

Node.js的事件处理机制服务器

    在Node.js中采用了非阻塞的I/O机制,在这种机制下应用程序所进行的处理都不会再结束以前阻碍其余处理的进行。这些处理都是相互独立的,每个事件处理完成以后,会执行一个回调函数。     Node.js在主线程里面维护了一个事件队列,当接到请求以后就会将请求做为一个事件放在这个事件队列中,而后继续接受其余的请求。当主线程空闲的时候就开始循环事件队列。检查队列中是否有须要处理的事件,若是须要处理的事件不是I/O任务,就亲自处理,经过回调函数返回到上层调用。若是是I/O任务,就从线程池里面拿出一个线程处理这个事件,而且指定回调函数,而后继续循环队列中的其余事件。多线程

Node.js事件环原理并发

    事件循环定义:当线程中的I/O任务完成以后就会执行指定的回调函数,而且将这个完成的事件放在事件队列的尾部,等待事件循环,当主线程再次循环到这个事件的时候,就会直接处理而且返回给上层调用,这个过程就是事件循环(Event Loop)。Node.js运行的原理图以下所示: 图片1.png异步

这个图是整个 Node.js 的运行原理,从左到右,从上到下,Node.js 被分为了四层,分别是 应用层、V8引擎层、Node API层和LIBUV层。函数

  • 应用层:即 JavaScript 交互层,常见的就是 Node.js 的模块,好比 http,fs。
  • V8引擎层:即利用 V8 引擎来解析JavaScript 语法,进而和下层 API 交互。
  • Node API层:为上层模块提供系统调用,通常是由 C 语言来实现,和操做系统进行交互。
  • LIBUV层:是跨平台的底层封装,实现了 事件循环、文件操做等,是 Node.js 实现异步的核心。     在Node.js的内部是经过线程池来完成I/O操做的,可是LIBUV层会针对不一样的操做系统平台的差别性实现了统一调用,Node.js的单线程指的是JavaScript运行在单线程中,并非说Node.js是单线程的,Node.js是一个多线程的平台,可是对于JavaScript的处理是单线程的。

Node.js特色及适用性高并发

  • Node.js在处理I/O任务的时候,会把任务交给线程池来处理,高效简单,所以Node.js适合用于处理I/O密集型的任务,可是不适合处理CPU密集型的任务,这是由于对于非I/O任务Node.js都是经过主线程亲自计算的,前面的任务没有处理完的状况下就会致使后来的任务堆积,就会出现响应缓慢的状况。即便是多核CPU在使用Node.js处理非I/O任务的时候,因为Node.js只有一个事件循环队列,因此只占用一个CPU内核,可是其余的内核都会处于空闲状态,所以会形成响应缓慢,CPU资源浪费的状况,因此Node.js不适合用于处理CPU密集型的任务。
  • Node.js还有一个优势是线程安全,单线程的JavaScript运行方式保证了线程的安全,不用担忧同一个变量被多个线程进行读写形成程序崩溃。同时也免去了在多线程编程中忘记对变量加锁或者解锁形成隐患。
相关文章
相关标签/搜索