什么是Node.js

Node.js从2009年降生至今,已生长了两年有余,其生长的速率有目共睹。从在github的接见量凌驾Rails,到去岁尾Node.jsS创始人Ryan Dalh加盟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创始人Ryan Dahl回想,他最初愿望采纳Ruby来写Node.js,然则厥后发明Ruby假造机的机能不能满足他的要求,厥后他尝试采纳V8引擎,所以挑选了C++言语。既然不是Javascript运用,为什么叫.js呢?因为Node.js是一个Javascript的运转环境。提到Javascript,人人起首想到的是一样平常运用的浏览器,当代浏览器包含了种种组件,包含衬着引擎、Javascript引擎等,个中Javascript引擎担任诠释实行网页中的Javascript代码。作为Web前端最主要的言语之一,Javascript一向是前端工程师的专利。不过,Node.js是一个后端的Javascript运转环境(支撑的体系包含*nux、Windows),这意味着你能够编写体系级或许效劳器端的Javascript代码,交给Node.js来诠释实行,简朴的敕令类似于:

#node helloworld.jsNode.js

采纳了Google Chrome浏览器的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为例:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(80, "127.0.0.1");

上面的代码搭建了一个简朴的http效劳器(运转示例布置在http://helloworld.cnodejs.net/中,读者能够接见),在当地监听80端口,关于恣意的http要求,效劳器都返回一个头部状况码为200、Content-Type’值为text/plain’的”Hello World“笔墨相应。从这个小例子中,我们能够看出几点:

  • Node.js的收集编程比较方便,供应的模块(在这里是http)开放了轻易上手的API接口,短短几行代码就能够构建效劳器。

  • 表现了事宜驱动、异步编程,在createServer函数的参数中指定了一个回调函数(采纳Javascript的匿名函数完成),当有http要求发送过来时,Node.js就会挪用该回调函数来处置惩罚要求并相应。固然,这个例子相对简朴,没有太多的事宜注册,在今后的文章中读者会看到更多的现实例子。

Node.js的特征

下面我们来说说Node.js的特征。事宜驱动、异步编程的特征适才已细致说过了,这里不再反复。
Node.js的机能不错。根据创始人Ryan Dahl的说法,机能是Node.js斟酌的主要因素,挑选C++和V8而不是Ruby或许其他的假造机也是基于机能的目标。Node.js在设想上也是比较斗胆勇敢,它以单历程、单线程情势运转(很受惊,对吧?这和Javascript的运转体式格局一致),事宜驱动机制是Node.js经由过程内部单线程高效率地保护事宜轮回行列来完成的,没有多线程的资本占用和上下文切换,这意味着面临大规模的http要求,Node.js依附事宜驱动搞定统统,习惯了传统言语的收集效劳开辟人员能够对多线程并发和合作非常熟习,然则面临Node.js,我们须要接收和明白它的特征。由此我们是不是能够推测出如许的设想会致使负载的压力集合在CPU(事宜轮回处置惩罚?)而不是内存(还记得Java假造机抛出OutOfMemory非常的日子吗?),眼见为实,不如来看看淘宝同享数据平台团队对Node.js的机能测试:

  • 物理机设置:RHEL 5.2、CPU 2.2GHz、内存4G

  • Node.js运用场景:MemCache代办,每次取100字节数据

  • 衔接池大小:50

  • 并发用户数:100

  • 测试效果(socket情势):内存(30M)、QPS(16700)、CPU(95%)

从上面的效果,我们能够看到在如许的测试场景下,qps能够到达16700次,内存仅占用30M(个中V8堆占用22M),CPU则到达95%,能够成为瓶颈。另外,另有不少实践者对Node.js做了机能剖析,总的来说,它的机能让人佩服,也是受欢迎的主要缘由。既然Node.js采纳单历程、单线程情势,那末在现在多核硬件盛行的环境中,单核机能精彩的Node.js怎样应用多核CPU呢?创始人Ryan Dahl发起,运转多个Node.js历程,应用某些通讯机制来谐和各项使命。现在,已有不少第三方的Node.js多历程支撑模块宣告,专栏背面的文章会细致报告Node.js在多核CPU下的编程。

Node.js的另一个特征是它支撑的编程言语是Javascript。关于动态言语和静态言语的优瑕玷比较在这里不再展开议论。只说三点:

var hostRequest = http.request(requestOptions,function(response) {
    var responseHTML ='';
    response.on('data', function (chunk) {
        responseHTML = responseHTML + chunk;
    });
    response.on('end',function(){
        console.log(responseHTML);
        // do something useful
   });
});

在上面的代码中,我们须要在end事宜中处置惩罚responseHTML变量,因为Javascript的闭包特征,我们能够在两个回调函数以外定义responseHTML变量,然后在data事宜对应的回调函数中不停修正其值,并终究在end事宜中接见处置惩罚。

  • Javascript作为前端工程师的主力言语,在手艺社区中有相称的号召力。而且,跟着Web手艺的不停生长,迥殊是前端的主要性增添,不少前端工程师最先试水”背景运用“,在很多采纳Node.js的企业中,工程师都示意因为习惯了Javascript,所以挑选Node.js。

  • Javascript的匿名函数和闭包特征非常合适事宜驱动、异步编程,从helloworld例子中我们能够看到回调函数采纳了匿名函数的情势来完成,很轻易。闭包的作用则更大,看下面的代码示例:

  • Javascript在动态言语中机能较好,有开辟人员对Javacript、Python、Ruby等动态言语做了机能剖析,发明Javascript的机能要好过其他言语,再加上V8引擎也是同类的佼佼者,所以Node.js的机能也受益个中。

Node.js生长简史

2009年2月,Ryan Dahl在博客上宣告预备基于V8建立一个轻量级的Web效劳器并供应一套库。
2009年5月,Ryan Dahl在GitHub上宣告了最初版本的部份Node.js包,随后几个月里,有人最先运用Node.js开辟运用。
2009年11月和2010年4月,两届JSConf大会都部署了Node.js的讲座。
2010年岁尾,Node.js取得云盘算效劳商Joyent赞助,创始人Ryan Dahl到场Joyent全职担任Node.js的生长。
2011年7月,Node.js在微软的支撑下宣告Windows版本。

Node.js运用案例

虽然Node.js降生方才两年多,然则其生长势头逐步赶超Ruby/Rails,我们在这里列举了部份企业运用Node.js的案例,听听来自客户的声响。
在交际网站LinkedIn最新宣告的挪动运用中,NodeJS是该挪动运用的背景基本。LinkedIn挪动开辟主管Kiran Prasad对媒体示意,其全部挪动软件平台都由NodeJS构建而成:

LinkedIn内部运用了大批的手艺,然则在挪动效劳器这一块,我们完整基于Node。
(运用它的缘由)第一,是因为其灵活性。第二,假如你相识Node,就会发明它最善于的事变是与其他效劳通讯。挪动运用必需与我们的平台API和数据库交互。我们没有做太多数据剖析。比拟之前采纳的Ruby on Rails手艺,开辟团队发明Node在机能方面进步很多。他们在每台物理机上跑了15个假造效劳器(15个实例),个中4个实例即可处置惩罚双倍流量。容量评价基于负载测试的效果。

企业社会化效劳网站Yammer则应用Node建立了针对其本身平台的跨域代办效劳器,第三方的开辟人员能够经由过程该效劳器完成从本身域托管的Javascript代码与Yammer平台API的AJAX通讯。Yammer平台手艺主管Jim Patterson对Node的长处和瑕玷提出了本身的意见:

(长处)因为Node是基于事宜驱动和无壅塞的,所以非常合适处置惩罚并发要求,因而构建在Node上的代办效劳器比拟其他手艺完成(如Ruby)的效劳器表现要好很多。另外,与Node代办效劳器交互的客户端代码是由javascript言语编写的,因而客户端和效劳器端都用同一种言语编写,这是非常美好的事变。
(瑕玷)Node是一个相对新的开源项目,所以不太稳固,它老是一向在变,而且缺乏足够多的第三方库支撑。看起来,就像是Ruby/Rails昔时的模样。

着名项目托管网站GitHub也尝试了Node运用。该Node运用称为NodeLoad,是一个存档下载效劳器(每当你下载某个存储分支的tarball或许zip文件时就会用到它)。GitHub之前的存档下载效劳器采纳Ruby编写。在旧体系中,下载存档的要求会建立一个Resque使命。该使命现实上在存档效劳器上运转一个git archive敕令,从某个文件效劳器中掏出数据。然后,初始的要求分派给你一个小型Ruby Sinatra运用守候该使命。它实在只是在搜检memcache flag是不是存在,然后再重定向到终究的下载地点上。旧体系运转约莫3个Sinatra实例和3个Resque worker。GitHub的开辟人员以为这是Node运用的好机会。Node基于事宜驱动,比拟Ruby的壅塞模子,Node能够更好地处置惩罚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,前后端开辟人员应当相识相干的内容。

    原文作者:colincto
    原文地址: https://segmentfault.com/a/1190000006925162
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞