在哪些情况下你要使⽤node?node的应⽤场景?
1.特点
(1)善于I/O,不善于计算
当应⽤程序需要处理⼤量并发的I/O,⽽在向客户端发出响应之前,应⽤程序内部并不需要进⾏⾮常复杂的处理的时候,node.js就⾮常适⽤。node.js也⾮常适⽤与websocket配合,开发长连接的实时交互应⽤程序。
node.js最擅长的就是任务调度,如果你的业务有很多CPU计算,实际上相当于这个计算阻塞了这个单线程就不适⽤于node开发。
(2)天⽣异步
2. nodeJs取舍特点:
可靠性低
⾼性能
单线程
异步事件驱动
⾮阻塞式IO
轻量⾼效
3.应⽤场景
⽹站开发
im即时聊天(socket. io)
api(移动端,pc)
HTTP  Proxy
前端构建⼯具
Node.js的特点
⾮阻塞异步io
例如,当在访问数据库取得数据的时候,需要⼀段时间。在传统的单线程处理机制中,在执⾏了访问数据库代码之后,整个线程都将暂停下来,等待数据库返回结果,才能执⾏后⾯的代码。也就是说,I/O阻塞了代码的执⾏,极⼤地降低了程序的执⾏效率。
由于 Node.js 中采⽤了⾮阻塞型I/O机制,因此在执⾏了访问数据库的代码之后,将⽴即转⽽执⾏其后⾯的代码,把数据库返回结果的处理代码放在回调函数中,从⽽提⾼了程序的执⾏效率。
当某个I/O执⾏完毕时,将以事件的形式通知执⾏I/O操作的线程,线程执⾏这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。
阻塞模式下,⼀个线程只能处理⼀项任务,要想提⾼吞吐量必须通过多线程。⽽⾮阻塞模式下,⼀个线程永远在执⾏计算操作,这个线程的CPU核⼼利⽤率永远是100%。所以,这是⼀种特别有哲理的解决⽅案:与其⼈多,但是好多⼈闲着;还不如⼀个⼈玩命,往死⾥⼲活⼉。单线程
在 Java、PHP 或者 等服务器端语⾔中,会为每⼀个客户端连接创建⼀个新的线程。⽽每个线程需要耗费⼤约2MB内存。也就是说,理论上,⼀个8GB内存的服务器可以同时连接的最⼤⽤户数为4000个左右。要让Web应⽤程序⽀持更多的⽤户,就需要增加服务器的数量,⽽ Web 应⽤程序的硬件成本当然就上升了。
Node.js不为每个客户连接创建⼀个新的线程,⽽仅仅使⽤⼀个线程。当有⽤户连接了,就触发⼀个内部事件,通过⾮阻塞I/O、事件驱动机制,让 Node.js 程序宏观上也是并⾏的。使⽤ Node.js ,⼀个8GB内存的服务器,可以同时处理超过4万⽤户的连接。
另外,单线程带来的好处,操作系统完全不再有线程创建、销毁的时间开销。但是单线程也有很多弊端,会在 Node.js 的弊端详细讲解,请继续看。
事件驱动
在 Node.js 中,客户端请求建⽴连接,提交数据等⾏为,会触发相应的事件。在Node.js 中,在⼀个时刻,只能执⾏⼀个事件回调函数,但是在执⾏⼀个事件回调函数的中途,⼜有其他事件产⽣,可以转⽽处理其他事件(⽐如,⼜有新⽤户连接了),然后返回继续执⾏原事件的回调函数,这种处理机制,称为“事件环”机制。
Node.js 底层是 C++(V8也是C++写的)。底层代码中,近半数都⽤于事件队列、回调函数队列的构建。⽤事件驱动来完成服务器的任务调度,这是⿁才才能想到的。针尖上的舞蹈,⽤⼀个线程,担负起了处理⾮常多的任务的使命。
注意这⾥的事件循环,也可以说是 Node.js 的⼀个精髓所在,下⾯引⽤⼀段 Node.js 官⽹的内容
引⽤Node官⽹中的⼀段内容:
注意:每个框将被称为事件循环的“阶段”。每个阶段都有⼀个要执⾏的回调FIFO队列。虽然每个阶段都以其⾃⼰的⽅式特殊,但通常情况下,当事件循环进⼊给定阶段时,它将执⾏特定于该阶段的任何操作,然后在该阶段的队列中执⾏回调,直到队列耗尽或最⼤回调数量为⽌已执⾏。当队列耗尽或达到回调限制时,事件循环将移⾄下⼀阶段,依此类推。关于事件循环是⼀个核⼼点,经常会被⾯试官考具体执⾏输出的问题,⼤家可以看我的这篇⽂章
跨平台
起初,Node 只能在 Linux 平台上运⾏。后来随着 Node的发展,微软注意到了它的存在,并投⼊了⼀个团队帮助 Node 实现 Windows 平台的兼容,在v0.6.0版本发布时,Node 已经能够直接在 Window 平台运⾏了。Node 是基于libuv实现跨平台的。
Node.js的弊端
单线程带来的弊端
Node.js中有⼀个特点就是单线程,它带来了很多好处,但是它也有弊端,单线程弱点如下。
⽆法利⽤多核CPU
错误会引起整个应⽤退出⽆法继续调⽤异步I/O
⼤量计算占⽤CPU导致⽆法继续调⽤异步I/O
以上确实是Node的弊端,但是都会有⼀些对应的解决⽅案:
弊端1:解决⽅案
(1)⼀些管理⼯具⽐如pm2,forever 等都可以实现创建多进程解决多核 CPU 的利⽤率问题。
(2)在v0.8版本之前,实现多进程可以使⽤child_process
(3)在v0.8版本之后,可以使⽤cluster模块,通过主从模式,创建多个⼯作进程解决多核CPU的利⽤率问题。
弊端2:解决⽅案
(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端⼝;
(2)⼀些管理⼯具⽐如pm2,forever 等都可以实现进程监控,错误⾃动重启等
(3)开多个进程监听同⼀个端⼝,使⽤Node提供的cluster模块;
(4)未出现cluster之前,也可以使⽤child_process,创建多⼦线程监听⼀个端⼝。
(5)这⾥说明下,有上⾯的这些解决⽅案,但是写node后端代码的时候,异常抛出try catch显得格外有必要。
弊端3:解决⽅案
(1)可以把⼤量的密集计算像上⾯⼀样拆分成多个⼦线程计算
但是如果不允许拆分,想计算100万的⼤数据,在⼀个单线程中,Node确实显得⽆能为⼒,这本⾝就是V8内存限制的弊端。
说明:child_process与cluster模块我会单独拿⼀篇⽂章来讲。值得开⼼的是上⾯这些弊端随着Node的版本更新,和新的api模块出现,好像解决了这些弊端。
调试
⽤过node的⼈可能第⼀时间就会想到debug太难了,没有stack trace,因此调试⽐较困难。
Node社区中的npm包
Node.js社区有很多包品质良莠不齐、如果你想偷懒⽽⼜刚好npm了⼀个有问题的包你就很⿇烦,因为代码是开源的,只能⾃⼰调试了。Node.js的应⽤场景
为什么要用ajax
介绍了Node.js的特点和弊端,再说⼀下Node.js的应⽤场景。
Node.js适合⽤来开发什么样的应⽤程序呢?
善于I/O,不善于计算。因为Node.js最擅长的就是任务调度,如果你的业务有很多的 CPU 计算,实际上也相当于这个计算阻塞了这个单线程,就不太适合Node开发,但是也不是没有解决⽅案,只是说不太适合。
当应⽤程序需要处理⼤量并发的I/O,⽽在向客户端发出响应之前,应⽤程序内部并不需要进⾏⾮常复杂的处理的时候,Node.js⾮常适合。Node.js也⾮常适合与websocket配合,开发长连接的实时交互应⽤程序。
具体场景可以表现为如下:
第⼀⼤类:⽤户表单收集系统、后台管理系统、实时交互系统、考试系统、联⽹软件、⾼并发量的web应⽤程序;
第⼆⼤类:基于web、canvas等多⼈联⽹游戏;
第三⼤类:基于web的多⼈实时聊天客户端、聊天室、图⽂直播;
第四⼤类:单页⾯浏览器应⽤程序;
第五⼤类:操作数据库、为前端和移动端提供基于json的API;
第六⼤类,....
其特点为:
1. 它是⼀个Javascript运⾏环境
2. 依赖于Chrome V8引擎进⾏代码解释
3. 事件驱动
4. ⾮阻塞I/O
5. 轻量、可伸缩,适于实时数据交互应⽤
6. 单进程,单线程
⼆. NodeJS带来的对系统瓶颈的解决⽅案
它的出现确实能为我们解决现实当中系统瓶颈提供了新的思路和⽅案,下⾯我们看看它能解决什么问题。
1. 并发连接
举个例⼦,想象⼀个场景,我们在银⾏排队办理业务,我们看看下⾯两个模型。
(1)系统线程模型:
系统线程模型
这种模型的问题显⽽易见,服务端只有⼀个线程,并发请求(⽤户)到达只能处理⼀个,其余的要先等待,这就是阻塞,正在享受服务的请求阻塞后⾯的请求了。
(2)多线程、线程池模型:
多线程、线程池模型
这个模型已经⽐上⼀个有所进步,它调节服务端线程的数量来提⾼对并发请求的接收和响应,但并发量
⾼的时候,请求仍然需要等待,它有个更严重的问题。到代码层⾯上来讲,我们看看客户端请求与服务端通讯的过程:
客户端请求与服务端通讯的过程
服务端与客户端每建⽴⼀个连接,都要为这个连接分配⼀套配套的资源,主要体现为系统内存资源,以PHP为例,维护⼀个连接可能需要20M的内存。这就是为什么⼀般并发量⼀⼤,就需要多开服务器。
那么NodeJS是怎么解决这个问题的呢?我们来看另外⼀个模型,想象⼀下我们在快餐店点餐吃饭的场景。
(3)异步、事件驱动模型
异步、事件驱动模型
我们同样是要发起请求,等待服务器端响应;但是与银⾏例⼦不同的是,这次我们点完餐后拿到了⼀个号码,拿到号码,我们往往会在位置上等待,⽽在我们后⾯的请求会继续得到处理,同样是拿了⼀个号码然后到⼀旁等待,接待员能⼀直进⾏处理。
等到饭菜做号了,会喊号码,我们拿到了⾃⼰的饭菜,进⾏后续的处理(吃饭)。这个喊号码的动作在
NodeJS中叫做回调(Callback),能在事件(烧菜,I/O)处理完成后继续执⾏后⾯的逻辑(吃饭),这体现了NodeJS的显著特点,异步机制、事件驱动整个过程没有阻塞新⽤户的连接(点餐),也不需要维护已经点餐的⽤户与厨师的连接。
基于这样的机制,理论上陆续有⽤户请求连接,NodeJS都可以进⾏响应,因此NodeJS能⽀持⽐Java、PHP程序更⾼的并发量虽然维护事件队列也需要成本,再由于NodeJS是单线程,事件队列越长,得到响应的时间就越长,并发量上去还是会⼒不从⼼。
总结⼀下NodeJS是怎么解决并发连接这个问题的:更改连接到服务器的⽅式,每个连接发射(emit)⼀个在NodeJS引擎进程中运⾏的事件(Event),放进事件队列当中,⽽不是为每个连接⽣成⼀个新的OS线程(并为其分配⼀些配套内存)。
2. I/O阻塞
NodeJS解决的另外⼀个问题是I/O阻塞,看看这样的业务场景:需要从多个数据源拉取数据,然后进⾏处理。
(1)串⾏获取数据,这是我们⼀般的解决⽅案,以PHP为例I/O阻塞-PHP为例
假如获取profile和timeline操作各需要1S,那么串⾏获取就需要2S。
(2)NodeJS⾮阻塞I/O,发射/监听事件来控制执⾏过程
⾮I/O阻塞-PHP为例
NodeJS遇到I/O事件会创建⼀个线程去执⾏,然后主线程会继续往下执⾏的,因此,拿profile的动作触发⼀个I/O事件,马上就会执⾏拿timeline的动作,两个动作并⾏执⾏,假如各需要1S,那么总的时间也就是1S。它们的I/O操作执⾏完成后,发射⼀个事件,profile和timeline,事件代理接收后继续往下执⾏后⾯的逻辑,这就是NodeJS⾮阻塞I/O的特点。
总结⼀下:Java、PHP也有办法实现并⾏请求(⼦线程),但NodeJS通过回调函数(Callback)和异步机制会做得很⾃然。
三. NodeJS的优缺点
优点:1. ⾼并发(最重要的优点)
2. 适合I/O密集型应⽤
缺点:1. 不适合CPU密集型应⽤;CPU密集型应⽤给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运⾏的计算(⽐如⼤循环),将会导致CPU时间⽚不能释放,使得后续I/O⽆法发起;
解决⽅案:分解⼤型运算任务为多个⼩任务,使得运算能够适时释放,不阻塞I/O调⽤的发起;
2. 只⽀持单核CPU,不能充分利⽤CPU
3. 可靠性低,⼀旦代码某个环节崩溃,整个系统都崩溃
原因:单进程,单线程
解决⽅案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端⼝;
(2)开多个进程监听同⼀个端⼝,使⽤cluster模块;
4. 开源组件库质量参差不齐,更新快,向下不兼容
5. Debug不⽅便,错误没有stack trace
四. 适合NodeJS的场景
1. RESTful API
这是NodeJS最理想的应⽤场景,可以处理数万条连接,本⾝没有太多的逻辑,只需要请求API,组织数
据进⾏返回即可。它本质上只是从某个数据库中查⼀些值并将它们组成⼀个响应。由于响应是少量⽂本,⼊站请求也是少量的⽂本,因此流量不⾼,⼀台机器甚⾄也可以处理最繁忙的公司的API需求。
2. 统⼀Web应⽤的UI层
⽬前MVC的架构,在某种意义上来说,Web开发有两个UI层,⼀个是在浏览器⾥⾯我们最终看到的,另⼀个在server端,负责⽣成和拼接页⾯。
不讨论这种架构是好是坏,但是有另外⼀种实践,⾯向服务的架构,更好的做前后端的依赖分离。如果所有的关键业务逻辑都封装成REST 调⽤,就意味着在上层只需要考虑如何⽤这些REST接⼝构建具体的应⽤。那些后端程序员们根本不操⼼具体数据是如何从⼀个页⾯传递到另⼀个页⾯的,他们也不⽤管⽤户数据更新是通过Ajax异步获取的还是通过刷新页⾯。
3. ⼤量Ajax请求的应⽤
例如个性化应⽤,每个⽤户看到的页⾯都不⼀样,缓存失效,需要在页⾯加载的时候发起Ajax请求,NodeJS能响应⼤量的并发请求。  总⽽⾔之,NodeJS适合运⽤在⾼并发、I/O密集、少量业务逻辑的场景。
五. 结尾
其实NodeJS能实现⼏乎⼀切的应⽤,我们考虑的点只是适不适合⽤它来做。
NodeJs的优势:现在的很多的服务器端的语⾔(PHP,JAVA,),有什么问题呢,现在的服务器端的语⾔在⽤户访问服务器时,为每个⽤户链接创建了⼀个线程,但每个线程⼤约要耗费2M的内存,如果⼀个8G内存的服务器,也就能链接4000个左右的⽤户,如果⽤户的链接数较⼤,就必须增加服务器的数量,⽽且现在⽤户的链接⽅式有很多(如app,⽹页同时访问),这就⼜涉及到服务器共享的问题,所以服务器怎么⽀持最⼤的同时链接⽤户量就成了⼀个问题;NodeJS修改了客户端到服务器端的链接⽅法,解决了这个问题,他不在为每个客户端创建⼀个新的线程,⽽是为每个客户端链接出发⼀个NodeJs内部进⾏处理的事件,所以NodeJS具备同时处理多达⼏万个⽤户的客户端链接的能⼒;NodeJS适合开发的应⽤程序:当应⽤程序需要处理⼤量并发的输⼊/输出,⽽在向客户端发出响应之前,应⽤程序内部并不需要进⾏⾮常复杂的处理的时候,我们应该考虑使⽤NodeJs来进⾏应⽤程序的开发,例如:1、聊天服务器:如果聊天的⼈很多,⽤户的与服务器之间的并发链接量很⼤,但是服务器端的数据处理并不复杂;2、综合类服务⽹站和电⼦商务⽹站的服务器:在这类⽹站中的服务器端,往往可能每秒存内可以接受多达上千条的数据并且需要将这些数据写⼊数据库中,NodeJs可以通过其队列机制将这些数据迅速写⼊缓存区中,然后再通过每⼀个单独的处理从缓存区中取出这些数据并将其写⼊数据库中,如果是其他的服务器(如Apache服务器或Tomcat服务器)的话,由于这些服务器采⽤的是阻塞型I/O机制,因此每条数据写⼊到数据库中都要等待⼀段时间(等上⼀条写完,才能写下⼀条),但是
NodeJs使⽤的是⾮阻塞的I/O机制,因此可以实现这些数据到数据库中的写⼊,⽽不必再为每条数据的写⼊⽽等待⼀段时间

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。