什么是节点.js?[已关闭]
我不完全理解Node.js的全部内容。也许是因为我主要是一个基于Web的业务应用程序开发人员。它是什么,它有什么用?
到目前为止,我的理解是:
- 编程模型是事件驱动的,尤其是它处理 I/O 的方式。
- 它使用JavaScript,解析器是V8。
- 它可以轻松用于创建并发服务器应用程序。
我的理解是否正确?如果是,那么事件 I/O 有什么好处,它只是对并发性的东西更多吗?另外,Node.js的方向是成为一个基于JavaScript(基于V8)的编程模型这样的框架吗?
我不完全理解Node.js的全部内容。也许是因为我主要是一个基于Web的业务应用程序开发人员。它是什么,它有什么用?
到目前为止,我的理解是:
我的理解是否正确?如果是,那么事件 I/O 有什么好处,它只是对并发性的东西更多吗?另外,Node.js的方向是成为一个基于JavaScript(基于V8)的编程模型这样的框架吗?
我在工作中使用Node.js,并发现它非常强大。被迫选择一个词来描述Node.js,我会说“有趣”(这不是一个纯粹的积极形容词)。社区充满活力且不断增长。JavaScript,尽管它很奇怪,但它可以成为一种很好的编程语言。你每天都会重新思考自己对“最佳实践”和结构良好的代码模式的理解。现在有一股巨大的思想能量流入Node.js,在其中工作会让你接触到所有这些想法 - 伟大的精神举重。
Node.js在生产中绝对是可能的,但与文档似乎承诺的“交钥匙”部署相去甚远。使用Node.js v0.6.x,“集群”已经集成到平台中,提供了一个重要的构建块,但我的“生产.js”脚本仍然是大约150行逻辑来处理诸如创建日志目录,回收死工人等。对于“严肃”的生产服务,您还需要准备好限制传入连接并执行Apache为PHP所做的所有操作。公平地说,Ruby on Rails有这个确切的问题。它通过两种互补的机制来解决:1)将Ruby放在Rails/Node上.js专用Web服务器(用C编写并测试到地狱和后面)后面,如Nginx(或Apache / Lighttd)。Web 服务器可以高效地提供静态内容、访问日志记录、重写 URL、终止 SSL、强制实施访问规则以及管理多个子服务。对于命中实际节点服务的请求,Web 服务器代理请求。2)使用像Unicorn这样的框架,它将管理工作进程,定期回收它们等。我还没有找到一个Node.js服务框架,看起来完全成熟;它可能存在,但我还没有找到它,并且仍然在我手卷的“生产.js”中使用了大约150行。
阅读像Express这样的框架似乎标准的做法是通过一个万事通Node.js服务来提供一切服务......“app.use(express.static(__dirname + '/public'))”。对于低负载服务和开发,这可能很好。但是,一旦您尝试对服务施加大量时间负载并使其全天候运行,您很快就会发现推动大型站点拥有良好烘焙,强化的C代码(如Nginx)的动机,这些代码位于其站点前面并处理所有静态内容请求(...直到您设置了 CDN,如 Amazon CloudFront))。对于一个有点幽默和毫不掩饰的负面看法,看看这个家伙。
Node.js也发现越来越多的非服务用途。即使您使用其他内容来提供Web内容,您仍然可以使用Node.js作为构建工具,使用npm模块来组织代码,Browserify将其拼接成单个资产,并使用uglify-js将其缩小以进行部署。对于处理Web,JavaScript是一个完美的阻抗匹配,并且经常使它成为最简单的攻击途径。例如,如果你想浏览一堆JSON响应有效负载,你应该使用我的下划线-CLI模块,这是结构化数据的实用程序带。
有关JavaScript和Node.js的另一个观点,请查看从Java到Node.js,这是一篇关于Java开发人员学习Node.js的印象和经验的博客文章。
模块在考虑node时,请记住,您选择的JavaScript库将定义您的体验。大多数人至少使用两个,一个异步模式助手(Step,Futures,Async)和一个JavaScript糖模块(Underscore.js)。
Helper / JavaScript Sugar:
异步模式模块:
或者要阅读有关异步库的所有信息,请参阅此与作者的小组访谈。
网络框架:
测试:
另外,请查看推荐的Node.js模块的官方列表。但是,GitHub的Node Modules Wiki更加完整,并且是一个很好的资源。
要了解 Node,考虑一些关键的设计选择会很有帮助:
节点.js是基于事件的和异步/非阻塞的。事件,如传入的HTTP连接,将触发一个JavaScript函数,该函数执行一些工作并启动其他异步任务,例如连接到数据库或从另一台服务器提取内容。启动这些任务后,事件函数将完成,Node.js将返回到睡眠状态。一旦发生其他事情,例如正在建立的数据库连接或外部服务器响应内容,回调函数就会触发,并且会执行更多的JavaScript代码,从而可能启动更多的异步任务(如数据库查询)。通过这种方式,Node.js将很乐意为多个并行工作流交错活动,运行在任何时间点解锁的任何活动。这就是为什么Node.js在管理数千个并发连接方面做得如此出色。
为什么不像其他人一样为每个连接使用一个进程/线程呢?在 Node.js 中,新连接只是一个非常小的堆分配。启动新进程需要的内存要多得多,在某些平台上为兆字节。但真正的成本是与上下文切换相关的开销。当你有10^6个内核线程时,内核必须做很多工作来弄清楚接下来应该执行谁。为Linux构建O(1)调度程序已经做了很多工作,但最终,拥有单个事件驱动的进程比10^ 6个进程争夺CPU时间要高效得多。此外,在过载条件下,多进程模型的行为非常糟糕,使关键的行政和管理服务(尤其是SSHD)挨饿(这意味着您甚至无法登录盒子来弄清楚它到底有多糟糕)。
节点.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");
Now you can hit a URL and check the status of your running process. Add a few buttons, and you have a "management portal". If you have a running Perl / Python / Ruby script, just "throwing in a management portal" isn't exactly simple.
But isn't JavaScript slow / bad / evil / spawn-of-the-devil? JavaScript has some weird oddities, but with "the good parts" there's a very powerful language there, and in any case, JavaScript is THE language on the client (browser). JavaScript is here to stay; other languages are targeting it as an IL, and world class talent is competing to produce the most advanced JavaScript engines. Because of JavaScript's role in the browser, an enormous amount of engineering effort is being thrown at making JavaScript blazing fast. V8 is the latest and greatest javascript engine, at least for this month. It blows away the other scripting languages in both efficiency AND stability (looking at you, Ruby). And it's only going to get better with huge teams working on the problem at Microsoft, Google, and Mozilla, competing to build the best JavaScript engine (It's no longer a JavaScript "interpreter" as all the modern engines do tons of JIT compiling under the hood with interpretation only as a fallback for execute-once code). Yeah, we all wish we could fix a few of the odder JavaScript language choices, but it's really not that bad. And the language is so darn flexible that you really aren't coding JavaScript, you are coding Step or jQuery -- more than any other language, in JavaScript, the libraries define the experience. To build web applications, you pretty much have to know JavaScript anyway, so coding with it on the server has a sort of skill-set synergy. It has made me not dread writing client code.
Besides, if you REALLY hate JavaScript, you can use syntactic sugar like CoffeeScript. Or anything else that creates JavaScript code, like Google Web Toolkit (GWT).
Speaking of JavaScript, what's a "closure"? - Pretty much a fancy way of saying that you retain lexically scoped variables across call chains. ;) Like this:
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();
See how you can just use "myData" without doing anything awkward like stashing it into an object? And unlike in Java, the "myData" variable doesn't have to be read-only. This powerful language feature makes asynchronous-programming much less verbose and less painful.
Writing asynchronous code is always going to be more complex than writing a simple single-threaded script, but with Node.js, it's not that much harder and you get a lot of benefits in addition to the efficiency and scalability to thousands of concurrent connections...
I think the advantages are:
Web development in a dynamic language (JavaScript) on a VM that is incredibly fast (V8). It is much faster than Ruby, Python, or Perl.
Ability to handle thousands of concurrent connections with minimal overhead on a single process.
JavaScript is perfect for event loops with first class function objects and closures. People already know how to use it this way having used it in the browser to respond to user initiated events.
A lot of people already know JavaScript, even people who do not claim to be programmers. It is arguably the most popular programming language.
Using JavaScript on a web server as well as the browser reduces the impedance mismatch between the two programming environments which can communicate data structures via JSON that work the same on both sides of the equation. Duplicate form validation code can be shared between server and client, etc.