Answers:
我认为优点是:
在VM(V8)上以惊人的速度以动态语言(JavaScript)进行Web开发。它比Ruby,Python或Perl快得多。
能够在单个进程上以最小的开销处理数千个并发连接。
JavaScript非常适合具有一流函数对象和闭包的事件循环。人们已经知道如何在浏览器中使用它来响应用户启动的事件时使用这种方式。
许多人已经知道JavaScript,甚至不自称是程序员的人也是如此。它可以说是最受欢迎的编程语言。
在Web服务器和浏览器上使用JavaScript可以减少两个编程环境之间的阻抗失配,这两个编程环境可以通过JSON传递数据结构,在等式的两面都相同。可以在服务器和客户端等之间共享重复的表单验证代码。
我在工作中使用Node.js,发现它非常强大。我不得不选择一个词来描述Node.js,我会说“有趣”(这不是纯粹的肯定形容词)。社区充满活力且不断发展。尽管有很多奇怪的地方,JavaScript仍然可以成为一种很好的编程语言。而且,您每天都会重新考虑自己对“最佳实践”和结构良好的代码模式的理解。目前,Node.js中涌现出了无数的创意,并且将其付诸实践会让您沉浸在所有这些思维中-极大的心理举重。
绝对有可能在生产中使用Node.js,但与文档中似乎承诺的“交钥匙”部署相去甚远。使用Node.js v0.6.x,“集群”已集成到平台中,提供了基本的构建块之一,但是我的“ production.js”脚本仍然是约150行逻辑,可以处理诸如创建日志之类的事情目录,回收死掉的工作人员等。对于“严肃的”生产服务,您还需要准备节制传入的连接并执行Apache为PHP所做的所有工作。公平地说,Ruby on Rails 确实存在这个问题。它可以通过两种补充机制来解决:1)将Ruby放在Rails / Node上。Apache / Lighttd)。Web服务器可以有效地提供静态内容,访问日志记录,重写URL,终止SSL,强制执行访问规则以及管理多个子服务。对于命中实际节点服务的请求,Web服务器将通过代理进行代理。2)使用诸如Unicorn之类的框架来管理工作进程,定期回收它们,等等。我还没有找到看起来完全成熟的Node.js服务框架;它可能存在,但我还没有找到,仍然在我手工滚动的“ production.js”中使用了约150行。
像Express这样的阅读框架使标准做法似乎只是通过一项千篇一律的Node.js服务提供所有服务……“ app.use(express.static(__ dirname +'/ public'))” 。对于较低负载的服务和开发,可能很好。但是,一旦您尝试将大量时间加载到服务上并使其以24/7的速度运行,您就会很快发现促使大站点进行良好烘焙,强化的C代码(例如Nginx)在其站点前处理所有内容的动机。静态内容请求(...直到您设置CDN,例如Amazon CloudFront)。要对此采取一些幽默而毫不掩饰的否定态度,请参阅此人。
Node.js还发现越来越多的非服务用途。即使您正在使用其他内容来提供Web内容,您仍然可以使用Node.js作为构建工具,使用npm模块来组织代码,使用Browserify将其拼接为单个资产,并使用uglify-js来最小化部署。对于处理网络,JavaScript是完美的阻抗匹配,并且经常使其成为最简单的攻击途径。例如,如果您想浏览一堆JSON响应有效负载,则应使用我的underscore-CLI模块,即结构化数据的实用程序带。
有关JavaScript和Node.js的另一种观点,请查看从Java到Node.js,这是一篇有关Java开发人员对学习Node.js的印象和体验的博客文章。
模块 在考虑节点时,请记住,您选择的JavaScript库将定义您的体验。大多数人至少使用两个,一个异步模式帮助器(Step,Futures,Async)和一个JavaScript Sugar模块(Underscore.js)。
助手/ JavaScript Sugar:
异步模式模块:
或要阅读有关异步库的所有内容,请参阅作者的专访。
网络框架:
测试:
另外,查看推荐的Node.js模块的官方列表。但是,GitHub的 Node Modules Wiki更完整,是一个很好的资源。
要了解Node,考虑一些关键的设计选择会有所帮助:
Node.js是基于事件的,并且是异步 / 非阻塞的。事件(例如传入的HTTP连接)将触发执行一些工作的JavaScript函数,并启动其他异步任务,例如连接到数据库或从另一台服务器提取内容。一旦启动了这些任务,事件函数就会完成,Node.js会重新进入睡眠状态。一旦发生其他情况,例如建立数据库连接或外部服务器响应内容,则回调函数将触发,并且将执行更多JavaScript代码,从而有可能启动更多异步任务(如数据库查询)。这样,Node.js将愉快地交错多个并行工作流的活动,在任何时间点运行不受阻碍的任何活动。这就是为什么Node.js出色地管理数千个同时连接的原因。
为什么不像其他所有人一样,仅对每个连接使用一个进程/线程?在Node.js中,新连接只是很小的堆分配。启动新进程将占用更多内存,在某些平台上为1 MB。但是实际成本是与上下文切换相关的开销。当您有10 ^ 6个内核线程时,内核必须做很多工作来弄清楚下一步应该执行谁。为Linux构建O(1)调度程序需要做大量工作,但最后,只有单个事件驱动的进程比争夺CPU时间的10 ^ 6进程更有效。此外,在过载情况下,多进程模型的运行情况非常差,使关键的管理和管理服务(尤其是SSHD)饿死了(这意味着您甚至无法登录到该盒子中来弄清楚它到底有多麻烦)。
Node.js是唯一的且无锁。Node.js作为一个非常刻意的设计选择,每个进程只有一个线程。因此,根本上不可能有多个线程同时访问数据。因此,不需要锁。线程很难。真的很辛苦。如果您不相信这一点,则说明您没有完成足够的线程编程。正确地锁定是很难的,并且会导致难以发现的错误。消除锁和多线程可以使最讨厌的错误类别之一消失。这可能是节点的最大优势。
但是我如何利用我的16芯盒呢?
两种方式:
Node.js可以让您做一些真正强大的事情而不会费力。假设您有一个执行各种任务的Node.js程序,在 TCP端口上侦听命令,并对某些图像进行编码,无论如何。使用五行代码,您可以添加基于HTTP的Web管理门户,以显示活动任务的当前状态。这很容易做到:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");
现在,您可以单击一个URL并检查运行进程的状态。添加一些按钮,您将获得一个“管理门户”。如果您具有正在运行的Perl / Python / Ruby脚本,那么仅仅“抛出管理门户”并不十分简单。
但是JavaScript不是慢/不好/恶/恶魔衍生吗?JavaScript有一些奇怪的怪异之处,但是“好部分”中存在着一种非常强大的语言,无论如何,JavaScript是客户端(浏览器)上的THE语言。JavaScript将保留下来;其他语言则将其定位为IL,世界一流的人才正在竞争生产最先进的JavaScript引擎。由于JavaScript在浏览器中的作用,为了使JavaScript快速发展,人们投入了大量的工程工作。 V8是最新的,最强大的JavaScript引擎,至少在本月才是如此。它在效率和稳定性方面都吹灭了其他脚本语言(在您看来,Ruby)。而且只有在Microsoft,Google和Mozilla的庞大团队致力于解决这个问题,并争夺构建最佳JavaScript引擎的情况下,这种情况才会变得更好(它不再是JavaScript“解释器”,因为所有现代引擎都在处理大量的JIT)在幕后进行编译,仅将其解释为一次执行代码的备用。是的,我们都希望我们可以修复一些奇怪的JavaScript语言选择,但实际上还不错。而且该语言是如此灵活,以至于您实际上不是在编写JavaScript,而是在编写Step或jQuery-与其他任何一种语言相比,在JavaScript中,库定义了这种体验。要构建Web应用程序,无论如何您几乎都必须了解JavaScript,因此在服务器上进行编码具有某种技能组合的协同作用。它使我不必担心编写客户端代码。
此外,如果您真的讨厌JavaScript,则可以使用语法糖(例如CoffeeScript)。或其他任何创建JavaScript代码的东西,例如Google Web Toolkit(GWT)。
说到JavaScript,什么是“关闭”?-几乎可以说是您在整个调用链中保留了词法范围的变量。;) 像这样:
var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();
看看如何只使用“ myData”而不做任何麻烦的事情,例如将其存储到对象中?而且与Java不同,“ myData”变量不必是只读的。这种强大的语言功能使异步编程的冗长程度和痛苦减轻了。
编写异步代码总是比编写简单的单线程脚本更为复杂,但是使用Node.js并不会困难得多,除了可以提高数千个并发连接的效率和可伸缩性之外,您还可以获得很多好处。 ..
V8是JavaScript的实现。它使您可以运行独立的JavaScript应用程序(以及其他功能)。
Node.js只是为V8编写的一个库,它可以进行事件I / O。这个概念是有点棘手解释,我相信有人会比我更好的解释回答...要点是,而不是做一些输入或输出,等待它的出现,你就不要等待完成它。因此,例如,询问文件的最后编辑时间:
// Pseudo code
stat( 'somefile' )
这可能需要几毫秒,也可能需要几秒钟。使用事件化的I / O,您只需触发请求,而不必等待,而是附加一个在请求完成时运行的回调:
// Pseudo code
stat( 'somefile', function( result ) {
// Use the result here
} );
// ...more code here
这使其非常类似于浏览器中的JavaScript代码(例如,具有Ajax样式功能)。
有关更多信息,您应该查看文章Node.js确实令人兴奋,这是我对库/平台的介绍...我发现它相当不错。
关于如何管理模板以及如何对其进行逐步增强的两个很好的例子。您只需要一些轻量级的JavaScript代码即可使其完美运行。
我强烈建议您观看并阅读以下文章:
选择任何一种语言,并尝试记住如何管理HTML文件模板以及在DOM结构中更新单个CSS类名称的操作(例如,用户单击菜单项,并希望将其标记为“选定”并更新页面内容)。
使用Node.js,就像在客户端JavaScript代码中一样简单。获取您的DOM节点,然后将CSS类应用于该节点。获取您的DOM节点,并获取您内容的innerHTML(您将需要一些其他的JavaScript代码来执行此操作。阅读本文以了解更多信息)。
另一个很好的例子是,您可以使网页与使用同一段代码打开或关闭的JavaScript兼容。想象一下,您有一个用JavaScript选择的日期,该日期允许您的用户使用日历来选择任何日期。您可以编写(或使用)同一段JavaScript代码,以使其与打开或关闭JavaScript一起使用。
有一个非常好的快餐店类比,可以最好地解释Node.js的事件驱动模型,请参阅全文,Node.js,医生办公室和快餐店–了解事件驱动的编程
总结如下:
如果快餐店遵循传统的基于线程的模型,则需要订购食物并排队等候,直到收到为止。在您完成订单后,您后面的人将无法订购。在事件驱动模型中,您订购食物,然后脱颖而出等待。然后其他所有人都可以自由订购。
Node.js是事件驱动的,但是大多数Web服务器都是基于线程的.York解释了Node.js的工作方式:
您使用Web浏览器在Node.js Web服务器上请求“ /about.html”。
Node.js服务器接受您的请求并调用一个函数以从磁盘检索该文件。
在Node.js服务器等待文件检索的同时,它为下一个Web请求提供服务。
检索文件时,Node.js服务器队列中插入了一个回调函数。
Node.js服务器执行该功能,在这种情况下,该功能将呈现“ /about.html”页面并将其发送回Web浏览器。”
问:编程模型是事件驱动的,尤其是它处理I / O的方式。
正确。它使用回调,因此任何访问文件系统的请求都将导致将请求发送到文件系统,然后Node.js将开始处理其下一个请求。一旦从文件系统获得响应,它就只会担心I / O请求,这时它将运行回调代码。但是,可以发出同步I / O请求(即阻止请求)。由开发人员决定是在异步(回调)还是同步(等待)之间选择。
问:它使用JavaScript,解析器为V8。
是
问:可以轻松地用于创建并发服务器应用程序。
是的,尽管您需要手工编写很多JavaScript。最好看一下框架,例如http://www.easynodejs.com/,该框架随附完整的在线文档和示例应用程序。