我没有完全了解Node.js的全部含义。也许是因为我主要是基于Web的业务应用程序开发人员。它是什么,有什么用?
到目前为止,我的理解是:
我认为优点是:
在VM(V8)上以惊人的速度以动态语言(JavaScript)进行Web开发。它比Ruby,Python或Perl快得多。
能够在单个进程上以最小的开销处理数千个并发连接。
JavaScript非常适合具有一流函数对象和闭包的事件循环。人们已经知道如何以这种方式使用它,并且已经在浏览器中使用它来响应用户启动的事件。
许多人已经知道JavaScript,甚至不自称是程序员的人也是如此。它可以说是最流行的编程语言。
在网络服务器和浏览器上使用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模块,即结构化数据的实用程序带。
优点缺点:
与简单的每个请求一个流程模型(LAMP):
模块 在考虑节点时,请记住,你选择的JavaScript库将定义你的体验。大多数人至少使用两个,一个异步模式帮助器(Step,Futures,Async)和一个JavaScript Sugar模块(Underscore.js)。
助手/ JavaScript Sugar:
步骤 -一种非常优雅的方式来表示串行和并行动作的组合。我个人的建议。有关步骤代码的外观,请参阅我的文章。 期货 -通过需求表达订购的方式更加灵活(这真的是一件好事吗?)。可以表示“并行启动a,b,c。当A和B完成时,启动AB。当A和C完成时,启动AC”。这种灵活性需要格外小心,以避免工作流程中的错误(例如从不调用回调或多次调用)。请参阅Raynos的有关使用期货的文章(这是使我“获得”期货的文章)。 - 异步 -更传统的库,每种模式只有一种方法。我从此开始,然后再宗教化为step并随后意识到,Async中的所有模式都可以用一个更具可读性的范例在Step中表达。 - TameJS-由OKCupid编写的,它是一个预编译器,它添加了新的语言原始语“ await”以优雅地编写串行和并行工作流。该模式看起来很棒,但是它确实需要预编译。我仍在决定这一点。 - StreamlineJS -TameJS的竞争对手。我倾向于驯服,但你可以下定决心。 或要阅读有关异步库的所有内容,请参见作者的专访。
网络框架:
jQuery虽然从技术上讲不是节点模块,但jQuery迅速成为客户端用户界面的实际标准。jQuery提供了类似于CSS的选择器来“查询”可以随后操作的DOM元素集(集合处理程序,属性,样式等)。同样,Twitter的Bootstrap CSS框架,用于MVC模式的Backbone.js和Browserify.js可以将所有JavaScript文件缝合到一个文件中。这些模块都已成为事实上的标准,因此如果你没有听说过它们,则至少应检查一下它们。 测试:
JSHint-必须使用;我一开始没有使用它,现在似乎无法理解。JSLint重新添加了你使用Java之类的编译语言获得的许多基本验证。括号不匹配,未声明的变量,许多形状和大小的类型。你还可以启用各种形式的所谓的“肛门模式”,在其中验证空白样式和其他样式,如果那是你的茶,就可以了-但真正的价值来自于获得有关确切行号的即时反馈你忘记了结束“)” …而不必运行你的代码并点击令人讨厌的行。“ JSHint”是Douglas Crockford的JSLint的更可配置的变体。
Zombie-无头测试HTML和JavaScript的使用JSDom作为一个虚拟的“浏览器”。非常强大的东西。将其与Replay结合使用,可以对浏览器内的代码进行快速的确定性测试。
关于如何“思考”测试的评论:
要了解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芯盒呢?
两种方式:
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并不会困难得多,除了可以提高数千个并发连接的效率和可伸缩性之外,你还可以获得很多好处。 ..