Nodejs目前处境稍显尴尬,不少语言都已经拥有异步非阻塞的能力。阿里的思路是比较合适的,可是必需要注意,绝对不能让node作太多的业务逻辑,他只适合接收生成好的数据,而后或渲染后,或直接发送到客户端。html
为何nodejs 还能够成为主流技术哪?前端
是由于nodejs 对于大前端来讲仍是很是重要的技术!!!若是你理解nodejs 的编程原理,很容易就会理解angularjs,reactjs 和vuejs 的设计原理。vue
Node是一个服务器端JavaScript解释器,用于方便地搭建响应速度快、易于扩展的网络应用。Node使用事件驱动,非阻塞I/O 模型而得以轻量和高效,很是适合在分布式设备上运行数据密集型的实时应用。
Node是一个可让JavaScript运行在浏览器以外的平台。它实现了诸如文件系统、模块、包、操做系统 API、网络通讯等Core JavaScript没有或者不完善的功能。历史上将JavaScript移植到浏览器外的计划不止一个,但Node.js 是最出色的一个。node
V8 JavaScript引擎是Google用于其Chrome浏览器的底层JavaScript引擎。不多有人考虑JavaScript在客户机上实际作了些什么!react
实际上,JavaScript引擎负责解释并执行代码。Google使用V8建立了一个用C++编写的超快解释器,该解释器拥有另外一个独特特征;您能够下载该引擎并将其嵌入任何应用程序。V8 JavaScript引擎并不只限于在一个浏览器中运行。angularjs
所以,Node实际上会使用Google编写的V8 JavaScript引擎,并将其重建为可在服务器上使用。 ajax
在咱们使用Java,PHP等语言实现编程的时候,咱们面向对象编程是完美的编程设计,这使得他们对其余编程方法不屑一顾。殊不知大名鼎鼎Node使用的倒是事件驱动编程的思想。那什么是事件驱动编程。
事件驱动编程,为须要处理的事件编写相应的事件处理程序。代码在事件发生时执行。
为须要处理的事件编写相应的事件处理程序。要理解事件驱动和程序,就须要与非事件驱动的程序进行比较。实际上,现代的程序大可能是事件驱动的,好比多线程的程序,确定是事件驱动的。早期则存在许多非事件驱动的程序,这样的程序,在须要等待某个条件触发时,会不断地检查这个条件,直到条件知足,这是很浪费cpu时间的。而事件驱动的程序,则有机会释放cpu从而进入睡眠态(注意是有机会,固然程序也可自行决定不释放cpu),当事件触发时被操做系统唤醒,这样就能更加有效地使用cpu。
来看一张简单的事件驱动模型(uml): 数据库
事件驱动模型主要包含3个对象:事件源、事件和事件处理程序。编程
事件源:产生事件的地方(html元素)浏览器
事件:点击/鼠标操做/键盘操做等等
事件对象:当某个事件发生时,可能会产生一个事件对象,该时间对象会封装好该时间的信息,传递给事件处理程序
事件处理程序:响应用户事件的代码
运行原理
当咱们搜索Node.js时,夺眶而出的关键字就是 “单线程,异步I/O,事件驱动”,应用程序的请求过程能够分为俩个部分:CPU运算和I/O读写,CPU计算速度一般远高于磁盘读写速度,这就致使CPU运算已经完成,可是不得不等待磁盘I/O任务完成以后再继续接下来的业务。
因此I/O才是应用程序的瓶颈所在,在I/O密集型业务中,假设请求须要100ms来完成,其中99ms化在I/O上。若是须要优化应用程序,让他能同时处理更多的请求,咱们会采用多线程,同时开启100个、1000个线程来提升咱们请求处理,固然这也是一种可观的方案。
可是因为一个CPU核心在一个时刻只能作一件事情,操做系统只能经过将CPU切分为时间片的方法,让线程能够较为均匀的使用CPU资源。但操做系统在内核切换线程的同时也要切换线程的上线文,当线程数量过多时,时间将会被消耗在上下文切换中。因此在大并发时,多线程结构仍是没法作到强大的伸缩性。
那么是否能够另辟蹊径呢?!咱们先来看看单线程,《深刻浅出Node》一书提到 “单线程的最大好处,是不用像多线程编程那样到处在乎状态的同步问题,这里没有死锁的存在,也没有线程上下文切换所带来的性能上的开销”,那么一个线程一次只能处理一个请求岂不是无稽之谈,先让咱们看张图:
Node.js的单线程并非真正的单线程,只是开启了单个线程进行业务处理(cpu的运算),同时开启了其余线程专门处理I/O。当一个指令到达主线程,主线程发现有I/O以后,直接把这个事件传给I/O线程,不会等待I/O结束后,再去处理下面的业务,而是拿到一个状态后当即往下走,这就是“单线程”、“异步I/O”。
I/O操做完以后呢?Node.js的I/O 处理完以后会有一个回调事件,这个事件会放在一个事件处理队列里头,在进程启动时node会建立一个相似于While(true)的循环,它的每一次轮询都会去查看是否有事件须要处理,是否有事件关联的回调函数须要处理,若是有就处理,而后加入下一个轮询,若是没有就退出进程,这就是所谓的“事件驱动”。这也从Node的角度解释了什么是”事件驱动”。
在node.js中,事件主要来源于网络请求,文件I/O等,根据事件的不一样对观察者进行了分类,有文件I/O观察者,网络I/O观察者。事件驱动是一个典型的生产者/消费者模型,请求到达观察者那里,事件循环从观察者进行消费,主线程就能够快马加鞭的只关注业务不用再去进行I/O等待。
Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。咱们来看一个简单的例子,在 Java和 PHP 这类语言中,每一个链接都会生成一个新线程,每一个新线程可能须要 2 MB 的配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发链接数量是 4,000 个用户。随着您的客户群的增加,若是但愿您的 Web 应用程序支持更多用户,那么,您必须添加更多服务器。因此在传统的后台开发中,整个 Web 应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器可以处理的并发链接的最大数量。这个不一样的架构承载的并发数量是不一致的。
而Node的出现就是为了解决这个问题:更改链接到服务器的方式。在Node 声称它不容许使用锁,它不会直接阻塞 I/O 调用。Node在每一个链接发射一个在 Node 引擎的进程中运行的事件,而不是为每一个链接生成一个新的 OS 线程(并为其分配一些配套内存)。
如上所述,nodejs的机制是单线程,这个线程里面,有一个事件循环机制,处理全部的请求。在事件处理过程当中,它会智能地将一些涉及到IO、网络通讯等耗时比较长的操做,交由worker threads去执行,执行完了再回调,这就是所谓的异步IO非阻塞吧。可是,那些非IO操做,只用CPU计算的操做,它就本身扛了,好比算什么斐波那契数列之类。它是单线程,这些本身扛的任务要一个接着一个地完成,前面那个没完成,后面的只能干等。所以,对CPU要求比较高的CPU密集型任务多的话,就有可能会形成号称高性能,适合高并发的node.js服务器反应缓慢。
一、RESTful API
这是适合 Node 的理想状况,由于您能够构建它来处理数万条链接。它仍然不须要大量逻辑;它本质上只是从某个数据库中查找一些值并将它们组成一个响应。因为响应是少许文本,入站请求也是少许的文本,所以流量不高,一台机器甚至也能够处理最繁忙的公司的 API 需求。
二、实时程序
好比聊天服务
聊天应用程序是最能体现 Node.js 优势的例子:轻量级、高流量而且能良好的应对跨平台设备上运行密集型数据(虽然计算能力低)。同时,聊天也是一个很是值得学习的用例,由于它很简单,而且涵盖了目前为止一个典型的 Node.js 会用到的大部分解决方案。
三、单页APP
ajax不少。如今单页的机制彷佛很流行,好比phonegap作出来的APP,一个页面包打天下的例子比比皆是。
总而言之,NodeJS适合运用在高并发、I/O密集、少许业务逻辑的场景