Node.js到底是什么? html
Node.js到底是什么?
做者:koala 一个有趣的人
文章同步到github博客:https://github.com/koala-coding/goodBlog前端
前言node
若是你有必定的前端基础,好比 `HTML、CSS、JavaScript、jQuery;那么,Node.js 能让你以最低的成本快速过渡成为一个全栈工程师(我称这个全栈为伪全栈,我认为的全栈也要精通数据库,不喜勿喷),从而触及后端和移动端的开发。固然,Node.js也不是万能的、也不是说学了它就能够彻底取代后端的其余开发语言,它有本身的使命和擅长的应用领域。git
除此以外如今很是火热的 Vue.js,Rect.js ,等不少数据层动态交互优先选用了Node.js,一些比较流行的打包工具也是如此;综上,为你为何要学习它又增长了一大理由。程序员
Node.js 和传统的后端语言(好比PHP、JAVA等)相比,各有优缺点,各自擅长领域和侧重点不一样,所以,各有千秋、各有需求市场。Node.js 让咱们进行后端开发多了一种便捷的手段。因此你们也不要总说哪些语言是最好的,各有各的使命,嘿嘿。github
Node.js的特色web
非阻塞异步io面试
例如,当在访问数据库取得数据的时候,须要一段时间。在传统的单线程处理机制中,在执行了访问数据库代码以后,整个线程都将暂停下来,等待数据库返回结果,才能执行后面的代码。也就是说,I/O阻塞了代码的执行,极大地下降了程序的执行效率。数据库
因为 Node.js 中采用了非阻塞型I/O机制,所以在执行了访问数据库的代码以后,将当即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提升了程序的执行效率。npm
当某个I/O执行完毕时,将以事件的形式通知执行I/O操做的线程,线程执行这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。
阻塞模式下,一个线程只能处理一项任务,要想提升吞吐量必须经过多线程。而非阻塞模式下,一个线程永远在执行计算操做,这个线程的CPU核心利用率永远是100%。因此,这是一种特别有哲理的解决方案:与其人多,可是好多人闲着;还不如一我的玩命,往死里干活儿。
单线程
在 Java、PHP 或者 .net 等服务器端语言中,会为每个客户端链接建立一个新的线程。而每一个线程须要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器能够同时链接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就须要增长服务器的数量,而 Web 应用程序的硬件成本固然就上升了。
Node.js不为每一个客户链接建立一个新的线程,而仅仅使用一个线程。当有用户链接了,就触发一个内部事件,经过非阻塞I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。使用 Node.js ,一个8GB内存的服务器,能够同时处理超过4万用户的链接。
另外,单线程带来的好处,操做系统彻底再也不有线程建立、销毁的时间开销。可是单线程也有不少弊端,会在 Node.js 的弊端详细讲解,请继续看。
事件驱动
在 Node 中,客户端请求创建链接,提交数据等行为,会触发相应的事件。在 Node 中,在一个时刻,只能执行一个事件回调函数,可是在执行一个事件回调函数的中途,又有其余事件产生,能够转而处理其余事件(好比,又有新用户链接了),而后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。
Node.js 底层是 C++(V8也是C++写的)。底层代码中,近半数都用于事件队列、回调函数队列的构建。用事件驱动来完成服务器的任务调度,这是鬼才才能想到的。针尖上的舞蹈,用一个线程,担负起了处理很是多的任务的使命。
注意这里的事件循环,也能够说是 Node.js 的一个精髓所在,下面引用一段 Node.js 官网的内容
┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ close callbacks │ └───────────────────────────┘
引用Node官网中的一段内容:
注意:每一个框将被称为事件循环的“阶段”。
每一个阶段都有一个要执行的回调FIFO队列。虽然每一个阶段都以其本身的方式特殊,但一般状况下,当事件循环进入给定阶段时,它将执行特定于该阶段的任何操做,而后在该阶段的队列中执行回调,直到队列耗尽或最大回调数量为止已执行。当队列耗尽或达到回调限制时,事件循环将移至下一阶段,依此类推。
关于事件循环是一个核心点,常常会被面试官考具体执行输出的问题,你们能够看个人这篇文章
跨平台
起初,Node 只能在 Linux 平台上运行。后来随着Node的发展,微软注意到了它的存在,并投入了一个团队帮助 Node 实现 Windows 平台的兼容,在v0.6.0版本发布时,Node 已经可以直接在 Window 平台运行了。 Node 是基于libuv实现跨平台的。
Node.js的弊端
单线程带来的弊端
Node.js中有一个特色就是单线程,它带来了不少好处,可是它也有弊端,单线程弱点以下。
以上确实是Node的弊端,可是都会有一些对应的解决方案:
弊端1:解决方案
弊端2:解决方案
弊端3:解决方案
说明:child_process与cluster模块我会单独拿一篇文章来说。
值得开心的是上面这些弊端随着Node的版本更新,和新的api模块出现,好像解决了这些弊端。
调试
用过node的人可能第一时间就会想到debug太难了,没有stack trace,所以调试比较困难。
Node社区中的npm包
Node.js社区有不少包品质参差不齐、若是你想偷懒而又恰好npm了一个有问题的包你就很麻烦,由于代码是开源的,只能本身调试了。
Node.js的应用场景
介绍了Node.js的特色和弊端,再说一下Node.js的应用场景。
Node.js适合用来开发什么样的应用程序呢?
善于I/O,不善于计算。由于Node.js最擅长的就是任务调度,若是你的业务有不少的 CPU 计算,实际上也至关于这个计算阻塞了这个单线程,就不太适合Node开发,可是也不是没有解决方案,只是说不太适合。
当应用程序须要处理大量并发的I/O,而在向客户端发出响应以前,应用程序内部并不须要进行很是复杂的处理的时候,Node.js很是适合。Node.js也很是适合与web socket配合,开发长链接的实时交互应用程序。
具体场景能够表现为以下:
哪些大公司在用
参考文章:本文部份内容来自朴灵老师的《深刻浅出Node.js》
文章同步到
程序员成长指北(ID:coder_growth)