Node.js从2009年诞生至今已经发展了两年多,其成长速度有目共睹。从github访问量超越Rails,到去年底Node.jsS创始人RyanDalh加入Joyent获得企业资助,再到今年发布Windows移植版,Node.js的前景一直被看好得到技术界的肯定。InfoQ一直关注Node.js的发展,在今年的两场Qcon大会(北京站和杭州站)都有专门的演讲。为了更好的推动Node.js在国内的技术推广,我们决定开设“简单介绍Node.js”的专栏,邀请Node.js领域的布道者、开发者、技术大牛来谈谈Node.js的所有方面。让读者对Node.js有更深入的了解,并能够积极参与新技术的讨论和实践。专栏的第一篇文章《什么是Node.js》试图从各个角度讲解Node.js的基本概念、发展历程、优势等。不熟悉该领域的开发者可以通过本文学习一些Node.js的基础知识。说到名字,关于Node.js的技术报道越来越多。Node.js也有多种编写方式。有的写成NodeJS,有的写成Nodejs。哪个最标准?我们不妨按照官方说法。在Node.js的官网上,它的项目已经被称为“Node”或者“Node.js”,没有找到其他的字眼。“Node”用的最多,考虑到Node这个词的含义和用途太广,开发者容易产生误解。我们使用第二个名称——“Node.js”。js的后缀点明了Node项目的初衷。还有其他各种没有确切来源的名称。我们不建议使用它们。Node.js不是一个JS应用程序,而是一个JS运行平台。初学者看到Node.js这个名字,可能会误以为它是一个Javascript应用。其实Node.js是用C++语言编写的,是一个Javascript运行平台。环境。为什么要使用C++语言?根据Node.js创始人RyanDahl的回忆,他最初希望使用Ruby来编写Node.js,但后来发现Ruby虚拟机的性能无法满足他的要求。后来他尝试使用V8引擎,于是选择了C++语言。既然不是Javascript应用,为什么叫.js呢?因为Node.js是一个Javascript运行环境。提到Javascript,你首先想到的就是你日常使用的浏览器。现代浏览器包含各种组件,包括渲染引擎、Javascript引擎等,Javascript引擎负责解释和执行网页中的Javascript代码。Javascript作为Web前端最重要的语言之一,一直是前端工程师的专利。但是,Node.js是一个后端的Javascript运行环境(支持的系统包括*nux、Windows),也就是说你可以编写系统级或者服务端的Javascript代码,交给Node.js解释执行.简单的命令类似于:#nodehelloworld.jsNode.js采用了GoogleChrome浏览器的V8引擎,性能良好,提供了很多系统级的API,比如文件操作,网络编程等。浏览器端的Javascript代码在运行时会受到各种安全限制,在客户端系统上的运行受到限制。相比之下,Node.js是一个成熟的后台运行时,它为Javascript提供了许多其他语言可以提供的功能。Node.js采用事件驱动和异步编程。为网络服务设计事件驱动并不陌生。在一些传统语言的网络编程中,我们会用到回调函数。例如,当socket资源达到某个状态时,注册的回调函数就会被执行。Node.js的设计思想是事件驱动的,它提供的大部分API都是基于事件和异步的。以Net模块为例,net.Socket对象有以下事件:connect、data、end、timeout、drain、error、close等。使用Node.js的开发者需要根据自己的业务逻辑注册相应的回调函数.这些回调函数是异步执行的,这意味着虽然这些函数在代码结构中看起来是顺序注册的,但它们并不依赖于它们出现的先后顺序,而是等待相应的事件触发。事件驱动,异步编程设计(有兴趣的读者可以参考作者的另一篇文章《Node.js的异步编程风格》),重要的优点是充分利用系统资源,执行代码不阻塞等待某些操作完成,有限资源可以用于其他任务。这种设计非常适合后端网络服务编程,Node.js的目标也在这里。在服务器开发中,并发请求处理是一个大问题,阻塞函数会导致资源浪费和时间延迟。通过事件注册和异步函数,开发者可以提高资源利用率和性能。从Node.js提供的支持模块可以看出,包括文件操作在内的很多功能都是异步执行的,这与传统语言不同。另外,为了方便服务器开发,Node.js有很多网络模块。包括HTTP、DNS、NET、UDP、HTTPS、TLS等,开发者可以在此基础上快速搭建Web服务器。以简单的helloworld.js为例:varhttp=require('http');http.createServer(function(req,res){res.writeHead(200,{'Content-Type':'text/plain'});res.end('HelloWorld\n');}).listen(80,"127.0.0.1");上面代码搭建了一个简单的http服务器(运行示例部署在http://helloworld.cnodejs.net/,读者可以访问),在本地监听80端口,对于任何http请求,服务器都会返回一个“HelloWorld"标题状态代码为200且Content-Type'值为text/plain'的文本响应。从这个小例子,我们可以看出几点:Node.js网络编程更方便,提供的模块(这里是http)开放了简单易用的API接口,只需几行代码就可以搭建服务器代码。它体现了事件驱动和异步编程。在createServer函数的参数中指定了一个回调函数(由Javascript匿名函数实现)。当发送http请求时,Node.js会调用回调函数处理请求并做出响应。当然,这个例子比较简单,没有太多的事件注册。读者将在以后的文章中看到更多实用示例。Node.js的特点下面说说Node.js的特点。事件驱动和异步编程的特点,刚才已经详细讲过,这里不再赘述。Node.js表现良好。根据创始人RyanDahl的说法,性能是Node.js考虑的重要因素,选择C++和V8而不是Ruby或其他虚拟机也是基于性能。Node.js在设计上也比较大胆。它以单进程、单线程的方式运行(很惊讶吧?这和Javascript的运行方式是一致的),而事件驱动机制是Node.js通过内部的单线程高效维护了事件循环队列的实现没有多线程资源占用和上下文切换,这意味着面对大规模的http请求,Node.并发和协作很熟悉,但是面对Node.js,我们需要接受和理解它的特性。由此我们是否可以推测,这样的设计会导致负载的压力集中在CPU(事件循环处理?)而不是内存上(还记得Java虚拟机抛出OutOfMemory异常的日子吗?),看到相信,不如看看淘宝共享数据平台团队对Node.js的性能测试:物理机配置:RHEL5.2,CPU2.2GHz,内存4GNode.js应用场景:MemCache代理,每次取100bytesofdataconnectionpoolsize:50concurrentusers:100测试结果(socket方式):内存(30M),QPS(16700),CPU(95%)从上面的结果可以看出,在这样的测试场景下,qps可以达到16700次,内存只占30M(V8堆占22M),CPU达到95%,可能成为瓶颈。另外,很多从业者都对Node.js做过性能分析。总的来说,它的表现是有说服力的,这也是它受欢迎的重要原因。既然Node.js采用了单进程单线程的模式,那么单核性能优秀的Node.js如何在如今多核硬件大行其道的环境下发挥多核CPU的优势呢?创始人RyanDahl建议运行多个Node.js进程,使用某种通信机制来协调任务。目前已经发布了很多第三方的Node.js多进程支持模块。专栏后面的文章会详细介绍Node.js在多核CPU下的编程。Node.js的另一个特点是它支持的编程语言是Javascript。动态语言和静态语言的优缺点比较这里就不展开讨论了。只需三点:varhostRequest=http.request(requestOptions,function(response){varresponseHTML='';response.on('data',function(chunk){responseHTML=responseHTML+chunk;});response.on('end',function(){console.log(responseHTML);//做一些有用的事情});});上面代码中,我们需要在end事件中处理responseHTML变量,由于Javascript的闭包特性,我们可以在两个回调函数外定义responseHTML变量,然后在数据对应的回调函数中不断修改它的值事件,最后访问结束事件中的处理。Javascript作为前端工程师的主要语言,在技术社区具有相当大的号召力。而且,随着Web技术的不断发展,尤其是前端的重要性越来越高,很多前端工程师开始试水“后台应用”。在许多使用Node.js的公司中。节点。js。Javascript的匿名函数和闭包特性非常适合事件驱动和异步编程。从helloworld例子我们可以看出,回调函数是以匿名函数的形式实现的,非常方便。闭包发挥更大的作用。请参见以下代码示例:Javascript在动态语言中具有更好的性能。有开发者分析过Javacrit、Python、Ruby等动态语言的性能,发现Javascript的性能优于其他语言。此外,V8引擎也是同类中最好的,因此Node.js的性能也得益于它。Node.js发展简史2009年2月,RyanDahl在他的博客上宣布,他计划创建一个基于V8的轻量级Web服务器,并提供一组库。2009年5月,RyanDahl在GitHub上发布了一些Node.js包的初始版本,在接下来的几个月里,人们开始使用Node.js开发应用程序。2009年11月和2010年4月,两次JSConf大会安排了Node.js讲座。2010年底,Node.js获得云计算服务商Joyent的投资,创始人RyanDahl全职加入Joyent,负责Node.js的开发。2011年7月,在Microsoft的支持下,Node.js发布了Windows。Node.js应用案例Node.js虽然诞生不过两年多,但其发展势头已经逐渐超越了Ruby/Rails。这里我们列举一些企业应用Node.js听取客户心声的案例。在社交网站LinkedIn最新发布的移动应用中,NodeJS是移动应用的后台基础。LinkedIn移动开发总监KiranPrasad对媒体表示,其整个移动软件平台都是用NodeJS构建的:LinkedIn内部使用了很多技术,但在移动服务器方面,我们完全基于Node。(使用它的原因)首先,因为它的灵活性。其次,如果您了解Node,那么它最擅长的就是与其他服务进行通信。移动应用程序必须与我们的平台API和数据库交互。我们没有做太多的数据分析。与之前采用的RubyonRails技术相比,开发团队发现Node在性能方面有了很大的提升。他们在每台物理机上运行15个虚拟服务器(15个实例),其中4个实例可以处理两倍的流量。容量评估基于负载测试的结果。企业社交服务网站Yammer利用Node为自有平台创建了一个跨域代理服务器,第三方开发者可以通过它实现自有域托管的Javascript代码与Yammer平台API之间的AJAX通信。Yammer平台技术总监JimPatterson对Node的优缺点提出了自己的看法:(Advantages)由于Node是基于事件驱动和非阻塞的,非常适合处理并发请求,所以代理基于Node构建的服务器比其他具有Ruby等技术实现的服务器性能要好得多。另外,与Node代理服务器交互的客户端代码是用javascript编写的,所以客户端和服务器端都是用同一种语言编写的,这是一件很美妙的事情。(缺点)Node是一个比较新的开源项目,所以不稳定,总是在变化,缺乏足够的第三方库支持。看起来像Ruby/Rails曾经是。知名项目托管网站GitHub也尝试了Node应用。这个Node应用程序称为NodeLoad,是一个存档下载服务器(每当您下载存储库分支的tarball或zip文件时都会使用它)。GitHub之前的存档下载服务器是用Ruby写的。在旧系统中,下载档案的请求将创建一个Resque任务。该任务实际上在存档服务器上运行一个gitarchive命令,从某个文件服务器获取数据。然后,初始请求将您分派到一个等待任务的小型Rub??ySinatra应用程序。其实只是检查memcacheflag是否存在,然后重定向到最终的下载地址。旧系统运行大约3个Sinatra实例和3个Resqueworker。GitHub的开发人员将此视为Node应用程序的绝佳机会。Node是事件驱动的,Node可以比Ruby的阻塞模型更好地处理git归档。在写一个新的下载服务器的过程中,开发者觉得Node很适合这个功能。此外,他们还使用了Node库socket.io来监控下载状态。不仅在国外,Node的优势也引起了国内开发者的关注。淘宝其实已经应用了Node技术:MyFOX是一个数据处理中间件,负责从MySQL集群中提取数据,计算并输出统计结果。用户提交一条SQL语句,MyFOX根据SQL命令的语义生成各个数据库分片需要执行的查询语句,发送给各个分片,然后汇总计算结果。MyFOX的特点是CPU密集型,没有文件IO,只处理只读数据。起初MyFOX是用PHP写的,但是遇到了很多问题。比如PHP是单线程的,而MySQL需要阻塞查询,所以很难并发请求数据。后面的方案是使用nginx和dirzzle,基于HTTP协议实现接口,通过curl_multi_get命令请求。不过,MyFOX项目组最终还是决定使用Node.js来实现MyFOX。选择Node.js的原因有很多,比如考虑兴趣和社区发展,也有希望提高并发,排干CPU。例如,频繁的打开和关闭连接会导致大量端口处于等待状态。当并发数增加时,经常会因为端口不足(处于TIME_WAIT状态)而导致连接失败。以前经常通过修改系统设置来减少等待时间来避免这个错误,但是使用连接池可以很好的解决这个问题。此外,MyFOX曾经在某些缓存失效时会经历非常强烈的访问压力。使用Node.js,您可以共享查询状态并使某些请求“等待一段时间”,以便系统可以重新填充缓存内容。总结本文简要介绍了Node.js的基础知识,包括概念、特性、历史、案例等。作为一个只有2年历史的平台,Node.js的发展势头是有目共睹的。越来越多的公司开始关注和尝试Node.js。前后端开发人员应该了解相关内容。
