Node.jsNode.js简介•简单的说Node.js就是运行在服务端的JavaScript。•Node.js是一个基于ChromeJavaScript运行时建立的一个平台。•Node.js是一个事件驱动I/O服务端JavaScript环境(由C++编写),基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。Node.js的工作原理用户Request用户Request用户RequestNode.js进程Php模型用户Request用户Request用户RequestAPACHEPHP线程PHP线程PHP线程处理Request处理Request处理RequestNodeJS优缺点及适用场景讨论一.NodeJS的特点二.NodeJS带来的对系统瓶颈的解决方案三.NodeJS的优缺点四.适合NodeJS的场景NodeJS的特点•1.它是一个Javascript运行环境(C++实现)•2.依赖于ChromeV8引擎进行代码解释•3.事件驱动•4.非阻塞I/O•5.轻量、可伸缩,适于实时数据交互应用•6.单进程,单线程•7.模块化编程•8.事件轮询(eventloop)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为例假如获取profile和timeline操作各需要1S,那么串行获取就需要2S。(2)NodeJS非阻塞I/O,发射/监听事件来控制执行过程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,不能充分利用CPU3.可靠性低,一旦代码某个环节崩溃,整个系统都崩溃原因:单进程,单线程解决方案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;(2)开多个进程监听同一个端口,使用cluster模块;4.开源组件库质量参差不齐,更新快,向下不兼容5.Debug不方便,错误没有stacktrace四.适合NodeJS的场景1.RESTfulAPI这是NodeJS最理想的应用场景,可以处理数万条连接,本身没有太多的逻辑,只需要请求API,组织数据进行返回即可。它本质上只是从某个数据库中查找一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的API需求。2.统一Web应用的UI层目前MVC的架构,在某种意义上来说,Web开发有两个UI层,一个是在浏览器里面我们最终看到的,另一个在server端,负责生成和拼接页面。不讨论这种架构是好是坏,但是有另外一种实践,面向服务的架构,更好的做前后端的依赖分离。如果所有的关键业务逻辑都封装成REST调用,就意味着在上层只需要考虑如何用这些REST接口构建具体的应用。那些后端程序员们根本不操心具体数据是如何从一个页面传递到另一个页面的,他们也不用管用户数据更新是通过Ajax异步获取的还是通过刷新页面。3.大量Ajax请求的应用例如个性化应用,每个用户看到的页面都不一样,缓存失效,需要在页面加载的时候发起Ajax请求,NodeJS能响应大量的并发请求。总而言之,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景。花瓣网淘宝开放平台API调用Nodejs版本实现Cnode.org社区成功案例网易开源基于Node.js的游戏服务器框架pomeloNodeOS(NodeOS是采用NodeJS开发的一款友好的操作系统)EventLoop什么是EventLoop?EventLoop是一个很重要的概念,指的是计算机系统的一种运行机制。JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。本文参考C.AaronCois的《UnderstandingTheNode.jsEventLoop》,解释什么是EventLoop,以及它与JavaScript语言的单线程模型有何关系。想要理解EventLoop,就要从程序的运行模式讲起。运行以后的程序叫做进程(process),一般情况下,一个进程一次只能执行一个任务。如果有很多任务需要执行,不外乎三种解决方法。以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即采用上面的第一种方法。一旦遇到大量任务或者遇到一个耗时的任务,网页就会出现假死,因为JavaScript停不下来,也就无法响应用户的行为。你也许会问,JavaScript为什么是单线程,难道不能实现为多线程吗?这跟历史有关系。JavaScript从诞生起就是单线程。原因大概是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。后来就约定俗成,JavaScript为一种单线程语言。(WorkerAPI可以实现多线程,但是JavaScript本身始终是单线程的。)如果某个任务很耗时,比如涉及很多I/O(输入/输出)操作,那么线程的运行大概是下面的样子。上图的绿色部分是程序的运行时间,红色部分是等待时间。可以看到,由于I/O操作很慢,所以这个线程的大部分运行时间都在空等I/O操作的返回结果。这种运行方式称为同步模式(synchronousI/O)或堵塞模式(blockingI/O)。如果采用多线程,同时运行多个任务,那很可能就是下面这样。上图表明,多线程不仅占用多倍的系统资源,也闲置多倍的资源,这显然不合理。EventLoop就是为了解决这个问题而提出的。Wikipedia这样定义:EventLoop是一个程序结构,用于等待和发送消息和事件。简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为主线程;另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为EventLoop线程(可以译为消息线程)。上图主线程的绿色部分,还是表示运行时间,而橙色部分表示空闲时间。每当遇到I/O的时候,主线程就让EventLoop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,EventLoop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。可以看到,由于多出了橙色的空闲时间,所以主线程得以运行更多的任务,这就提高了效率。这种运行方式称为异步模式(asynchronousI/O)或非堵塞模式(non-blockingmode)。这正是JavaScript语言的运行方式。单线程模型虽然对JavaScript构成了很大的限制,但也因此使它具备了其他语言不具备的优势。如果部署得好,JavaScript程序是不会出现堵塞的,这就是为什么node.js平台可以用很少的资源,应付大流量访问的原因。Node.js语法第一个Node.js程序:HelloWorld!以下是我们的第一个Node.js程序:console.log(HelloWorld);保存该文件,并通过Node.js来执行:nodehelloworld.js程序执行后,正常的话,就会在终端输出HelloWorld。Node.js安装配置window和Linux上安装Node.js的方法Node.js安装包及源码下载地址为:。根据不同平台系统选择你需要的Node.js安装包。注意:Linux上安装Node.js需要安装Python2.6或2.7,不建议安装Python3.0以上版本。Windowv上安装Node.jsWindows安装包(.msi):32位安装包下载地址:位安装包下载地址:安装步骤:步骤1:双击下载后的安装包node-v0.10.26-x86.msi,如下所示:安装过程省略。。console.log(HelloWorld);保存该文件,并通过Node.js来执行:nodehelloworld.js程序执行后,正常的话,就会在终端输出HelloWorld。Node.js创建HTTP服务器如果我们使用PHP来编写后端的代码时,需要Apache或者Nginx的HTTP服务器,并配上mod_php5模块和php-cgi。从这个角度看,整个接收HTTP请求并提供Web页面的需求根本不需要PHP来处理。不过对Node.js来说,概念完全不一样了。使用Node.js时,我们不仅仅在实现一个应用,同时还实现了整个HTTP