初探node.js

什么是node.js

  1. node.js != Javascript
    事实上,Node.js采用C++语言编写而成,是一个Javascript的运行环境。

    • Node.js 是构建于Chrome的JavaScript引擎的
      Google的浏览器Chrome,有一个非常快速的JavaScript引擎,叫做V8。这个JS引擎可以被独立出来,该解释器拥有另一个独特特征;可以下载该引擎并将其嵌入任何 应用程序。Node.js就是建立在V8之上的。这也是为什么Node.js会运行的如此之快。对于开发者来说,有几个好处:
      • js完全通用
      • v8的发展影响着node.js
  2. Node.js 不仅仅是一个网页服务器或者平台
    Node.js 不是以网页为中心的。Node.js 是通用目的的JS运行时,带有很多功能强大的库。其中有一个库提供了 HTTP/HTTPS 的实现。

  3. Node.js是面向对象的
    Node.js的实质就是用Javascript的代码规范通过C++进行了实现和封装。一般在前端用js时,无非是ajax以及特效,仅仅针对一个页面。所以,不用面向对象也可以完成,但在后台,我们常用一些代码,所以进行封装,等用的时候新建一个对象。

  4. node.js能做什么?
    正如 JavaScript 为客户端而生,Node.js 为网络而生。Node.js 能做的远不止开发一个网站那么简单,使用 Node.js,你可以轻松地开发:

     具有复杂逻辑的网站;
     基于社交网络的大规模 Web 应用;
     Web Socket 服务器;
     TCP/UDP 套接字应用程序;
     命令行工具;
     交互式终端程序;
     带有图形用户界面的本地应用程序;
     单元测试工具;
     客户端 JavaScript 编译器。

    Node.js 内建了 HTTP 服务器支持,也就是说你可以轻而易举地实现一个网站和服务器的组合。这和 PHP、Perl 不一样,因为在使用 PHP 的时候,必须先搭建一个 Apache 之类的HTTP 服务器,然后通过 HTTP 服务器的模块加载或 CGI 调用,才能将 PHP 脚本的执行结果呈现给用户。而当你使用 Node.js 时,不用额外搭建一个 HTTP 服务器,因为 Node.js 本身就内建了一个。这个服务器不仅可以用来调试代码,而且它本身就可以部署到产品环境,它的性能足以满足要求。
    Node.js 还可以部署到非网络应用的环境下,比如一个命令行工具 。Node.js 还可以调用C/C++ 的代码,这样可以充分利用已有的诸多函数库,也可以将对性能要求非常高的部分用C/C++ 来实现。

  5. node.js的原理

    • 单线程
    • 异步非阻塞
    • 事件驱动
      用高并发解释

      一般来说,高并发解决方案会提供多线程模型,为每个业务逻辑提供一个线程,通过系统线程切换来来弥补同步I/O调用的时间开销。node.js使用的是单线程模型,对所有I/O都采用异步的请求方式,避免频繁的上下文切换,在node.js执行的时候维护着一个事件队列;程序在执行时进入事件循环等待下一个事件到来,每个异步I/O请求完成后都会被推送到事件队列中的等待执行。

    • 例子:
      对于一个简单的数据库访问操作,传统方式是这样实现的

      res = db.query('SELECT * from some_table');
      res.output();
      

      代码执行到第一行的时候线程会阻塞,等待query返回结果,然后继续处理。由于数据库查询、磁盘读写、网络通信等原因(所谓的I/O)阻塞时间会非常大(相对于CPU始终频率)。对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。
      node.js的处理方式:

      db.query('SELECT * from some_table',function(res) {   
              res.output();  
      });  
      

      query的第二个参数是一个回调函数,进程执行到db.query的时候不会等待结果返回,而是直接继续执行下面的语句,直到进入事件循环。当数据库执行结果返回的时候会将事件发送到事件队列,等到线程进入事件循环后才会调用之前的回调函数。
      node.js的异步机制是基于事件的,所有的I/O、网络通信、数据库查询都以非阻塞的方式执行,返回结果由事件循环来处理。node.js在同一时刻只会处理一个事件,完成后立即进入事件循环检查后面事件。这样CPU和内存在同一时间集中处理一件事,同时尽量让耗时的I/O等操作并行执行。

    • 事件循环机制
      所谓事件循环是指node.js会把所有的异步操作使用事件机制解决,有个线程在不断地循环检测事件队列。
      node.js中所有的逻辑都是事件的回调函数,所以node.js始终在事件循环中,程序入口就是事件循环第一个事件的回调函数。事件的回调函数中可能会发出I/O请求或直接发射( emit)事件,执行完毕后返回事件循环。事件循环会检查事件队列中有没有未处理的事件,直到程序结束。node.js的事件循环对开发者不可见,由libev库实现,libev不断检查是否有活动的、可供检测的事件监听器,直到检查不到时才退出事件循环,程序结束。
  6. node.js的优缺点
    • 优点:
      • 简单
      • 高性能,避免了频繁的线程切换开销,一个线程而已
      • 占用资源小,因为是单线程,在大负荷情况下,对内存占用仍然很低
      • 线程安全,没有加锁、解锁、死锁这些问题
    • 缺点:
      • CPU密集型任务存在短板
        事件循环机制,处理所有的请求。在事件处理过程中,它会智能地将一些涉及到IO、网络通信等耗时比较长的操作,交由worker threads去执行,执行完了再回调。但是,那些非IO操作,只用CPU计算的操作,就只能自己抗了。
      • 无法利用CPU的多核
        Node.js是单线程程序,它只有一个event loop,也只占用一个CPU/内核。
      • 如果有异常抛出,因为是单线程,整个项目将不可用