前言
本综述文章旨在帮助读者深刻理解下Node.js的本质,不去关注应用的细节,我认为真正的技术问题只有在动手写代码的时候才会遇到,那个阶段解决问题才是真正有意义的。
发展史
Node.js是Ryan Dahl 2009年对外发布的开源醒目,后来该项目被Joyent公司注意到并于2010年成为Joyent公司的一个子项目。2016年微软与Joyent公司合做,Node.js在windows上获得支持。
目前Node.js的版本为V6.11,周围已经造成了一个庞大的生态系统。
特性分析
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. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
上面是Node.js的官方描述,其中包含了Node.js最突出的特色。
一、Javascript runtime
这个描述解答了Node.js是什么的问题。它是一个Javascript 运行环境,相似于JVM之于Java,Node.js负责将Javascript转化为计算机能够识别的机器语言,同时对外提供API。传统上javascript依附于浏览器运行:
Node.js舍弃了浏览器,直接与js引擎对接,经过js引擎提供的API,Node.js能够完成其余后端语言(java)所能完成的一切功能,例如文件操做、网络通讯、设备管理等等。
下面说下Node.js所采用的js引擎——V8,这是目前世界上最快的js引擎,来自于Google Chrome项目,用C++语言编写,凭借Goole强大的技术支持,它的执行速度已经接近本地代码的执行速度。
除了V8之外,Node.js的仍是用了libev和libio库支持事件驱动和异步IO,如图所示,libuv是在libev和libeio的基础上抽象出的一层,对于POSIX系统,libuv利用epoll或者kqueue,而在Windows系统中,libuv使用了IOCP机制,以在不一样的平台下实现统一的高性能。
二、non-blocking IO and event-driven
先说说非阻塞IO,假设一个请求要读取数据库,db.query(select * from table),这个过程涉及磁盘读取与网络通讯,耗时很长,下面是几种服务器处理方式。
(1)若是是单线程+阻塞处理,线程会等待数据读取完毕才继续处理,同时后续的请求也得等待,这样的系统是不能忍受的。
(2)好在如今的后端容器都是支持多线程+阻塞的,其解决思路以下:
等待数据的线程继续等待,若是有新请求就从新建立一个线程,把cpu让给新的线程,待原线程获得数据后再把cpu切换给原线程。这样作有什么缺点么?
一是大量请求的状况下线程数目不断增长,浪费大量系统资源。
二是CPU在处理上下文切换的时候也浪费了很多时间。
(3)Node.js的解决思路则彻底不同。它被设计成单线程+非阻塞的。
全部的请求都在一个线程处理,一旦遇到耗时的请求,cpu不等待数据返回,而是接着处理后续的请求。那么问题来了,前面请求的数据到达后,如何返回给前端呢?这就要牵扯到Node.js的另一个特性——事件驱动。
在上面的简化模型中,全部的请求会依次进入线程的处理循环中,每一个请求自带回调函数,当耗时请求接受完数据后,回调函数自动被调用,从新进去循环处理,直到数据被返回给前端。
这样能让单个CPU充分运行起来,没有丝毫等待,同时避免了在不一样的线程中频繁切换引发的浪费。根据统计,Node.js相对传统的PHP+Nginx,在性能上有明显提高。
这种设计思路就是为微服务web系统而生的,由于web服务的特色就是请求密集、计算量小、要求快速响应。
Node.js的缺点
一、对于长期占据CPU的请求,后续的请求不能获得及时处理,产生较大延时,因此Node.js不适合计算密集型应用。
二、Node.js专一单线程处理,在多核环境中,必须总多进城才能充分利用多核,所以增长了设计难度。
三、Node.js的异步式编程模式不太符合通常的程序控制思路,给编码和调试带来很多困难。
经常使用辅助框架
一、npm(Node Package Manager)javascript
Node.js自己提供的API比较底层,彻底依靠Node.js实现一个系统对技术人员要求比较高。不过如今已经有大量的第三方支持供开发者使用。为了更好地使用和管理这些第三方提供的包,Node.js官方提供了一个基于命令行的包管理工具——npm.前端
npm彻底由javascript实现,不属于Node.js的一部分。不过在Node.js0.6开始,npm会自动包含在发行版中。java
二、Expressweb
参考
《Node.js开发指南》
《为何我要用 Node.js》http://blog.jobbole.com/53736/