Node.js特点和适用场景
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Node.js特点和适⽤场景
Node 起源
Node是由Ryan Dahl创造出来的,Ryan Dahl是⼀名资深的C/C++程序员,在创造出Node之前,他的主要⼯作都是围绕⾼性能web服务器来展开的,他找到了设计⾼性能web服务器的⼏个要点:事件驱动、⾮阻塞I/O,基于对已有的⼏种语⾔的对⽐和考量,Ryan Dahl选择了JavaScript作为Node的实现语⾔。
Node特点
1.异步I/O
在Node中,绝⼤多数的操作都以异步的⽅式进⾏调⽤,从⽂件读取到⽹络请求,均是如此,异步I/O意味着每个调⽤之间⽆须等待之前的I/O 调⽤结束,在编程模型上可以提升效率,如果存在两个⽂件读取任务,最终的耗时只取决于最慢的那个⽂件读取耗时,对于同步I/O⽽⾔,他的耗时是两个任务之和。
2.事件与回调
在Node中事件得到了⼴泛的应⽤,如创建⼀个服务器,我们会为器其绑定request对象,对于请求对象绑定data和end事件,同时在前端我们通常也是为Ajax请求绑定success事件、error事件等。
同样,在Node中回调也是⽆处不在的,事件的处理基本都是依赖回调来实现的,在JavaScript中,可以将函数作为对象传递给⽅法作为实参进⾏调⽤。
3.单线程
Node保持了JavaScript在浏览器中单线程的特点,⽽且在Node中,JavaScript与其余线程是⽆法共享任何状态的。
JavaScript采⽤单线程的原因和他最早的⽤途有关,最早在Web浏览器中,JavaScript主要做的是响应⽤户DOM操作以及做表单校验,这些功能使⽤单线程来处理完全够了,⽽且对于DOM操作来说,使⽤多线程的话还将造成线程安全问题,同时多线程还将给浏览器带来更⼤的内存消耗并降低CPU的使⽤率。
单就单线程本⾝来说,存在如下⼏个弱点:
1、⽆法利⽤多核CPU
2、错误会引起整个应⽤退出,应⽤的健壮性需要考虑
3、⼤量计算占⽤CPU将使阻塞程序的运⾏
严格来说,Node并⾮真正的单线程架构,Node⾃⾝还有⼀定的I/O线程存在,这些I/O线程由底层libuv处理,这就意味着Node在访问系统I/O 时还是多线程的,对于⽂件读取、SQL查询、⽹路请求这些具体操作,Node还是使⽤多线程来进⾏处理从⽽保证Node的处理效率。
为了应对单线程存在的CPU利⽤率问题,Node采⽤了多进程的架构,也就是著名的Master-Worker模式,⼜称主从模式,如下图所⽰,这种典型的⽤于并⾏处理业务的分布式架构具有较好的伸缩性和稳定性。
Node通过fork()复制的进程都是⼀个个独⽴的进程,这个进程中有着独⽴的V8实例,每个独⽴进程需要⾄少30毫秒的启动时间和⾄少10MB的内存,虽然fork()进程是有⼀定开销的,但是可以提⾼多核CPU的利⽤率,这在CPU普遍多核化的今天还是有很⼤的作⽤的,同时我们也应该认识到Node通过事件驱动的⽅式在单线程上已经可以解决⼤并发的问题,启动多进程只是为充分利⽤CPU资源。
Node的Master-Worker多进程模式中主进程和⼯作进程通过消息传递的形式⽽不是共享或直接操作资源的⽅式进⾏通信,通过fork()创建⼯作进程之后会在主进程和⼯作进程之间创建IPC通道,关于多进程相关内容,Node官⽅提供了cluster模块对进程进⾏管理,相关内容可参考cluster。
关于应⽤的健壮性问题,我们同样可以采⽤上述的Master-Worker模式,主进程只负责管理⼯作进程,具体的业务处理交由⼯作进程来完成,在⼯作进程中监听uncaughtException事件可以捕获未知的异常,然后告知主进程,主进程根据策略重新创建⼯作进程,或者直接退出主进程,这种情况代码中⼀定要给出⾜够的⽇志信息,通过⽇志监控任务及时产⽣报警。
4.跨平台
Node刚发布的时候,只能在Linux平台上运⾏,后来Node在架构层⾯进⾏了改动,在Node和操作系统之间引⼊了⼀层libuv,从⽽实现跨平台。
Node适合的应⽤场景
1.I/O密集型
Node异步I/O的特点使得他可以轻松⾯对I/O密集型的业务场景,处理效率将⽐同步I/O⾼,虽然同步I/O可以采⽤多线程或者多进程的⽅式进⾏,但是相⽐Node⾃带异步I/O的特性来说,将增加对内存和CPU的开销。
2.⾼并发场景
针对⾼并发请求场景,Node的异步I/O以及事件回调特点可以⾼效的处理并发请求,举个简单的例⼦:
有家快餐店,有⼀个收银员,有4个厨师,中午⾼峰期的时候回⼀下来很多⼈就餐,对于同步的场景,收银员收完钱后将订单给厨师,厨师开始做,做完之后把快餐交给顾客,然后再接受下⼀个顾客的订单,对于异步的场景,收银员收完钱后将订单给厨师同时给顾客⼀个号码牌,厨师开始做,这时候顾客可以去隔壁买个饮料,等到厨师做完叫好去取餐就⾏。
对于同步的场景如果需要增加顾客的处理速度,需要多
加⼏个收银员(多线程),这意味着需要更多的⼈⼒成本,虽然对于系统的处理能⼒(厨师)来说是⼀样的。
总结
总体来说Node的异步I/O能在开销固定的情况下极⼤的提⾼并发处理速度,适合⾼并发,I/O密集型的使⽤场景,同时由于单线程的特
点,Node程序不如多线程程序健壮性⾼,也不能利⽤多线程来使⽤多核CPU,不过对于Node来说,使⽤多进程的成本相对较⼩,上述问题都可以通过合理使⽤多进程来处理,最终程序的⾼效稳定运⾏还是取决于软件架构和编码质量。
为了便于学习,接下来还会写关于Node中Buffer、内存控制、程序测试等相关内容。