什么是Node.js?[关闭]

2020/09/25 09:01 · javascript ·  · 0评论

我没有完全了解Node.js的全部含义也许是因为我主要是基于Web的业务应用程序开发人员。它是什么,有什么用?

到目前为止,我的理解是:

  1. 编程模型是事件驱动的,尤其是它处理I / O的方式
  2. 它使用JavaScript,解析器为V8
  3. 它可以轻松用于创建并发服务器应用程序。

我的理解正确吗?如果是,那么事件I / O的好处是什么,并发性东西还有更多好处吗?另外,Node.js的发展方向是否像基于JavaScript(基于V8)的编程模型一样?

我认为优点是:

  1. 在VM(V8)上以惊人的速度以动态语言(JavaScript)进行Web开发。它比Ruby,Python或Perl快得多。

  2. 能够在单个进程上以最小的开销处理数千个并发连接。

  3. JavaScript非常适合具有一流函数对象和闭包的事件循环。人们已经知道如何在浏览器中使用它来响应用户启动的事件时使用这种方式。

  4. 很多人已经知道JavaScript,即使不是自称是程序员的人也是如此。它可以说是最受欢迎的编程语言。

  5. 在Web服务器和浏览器上使用JavaScript可以减少两个编程环境之间的阻抗失配,这两个编程环境可以通过JSON传递数据结构,而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一直是学习现代UI模式的“门户药物”。我不再害怕编写客户端代码。
  • 优点:倾向于鼓励进行正确的错误检查(几乎所有回调都会返回err,使程序员烦恼;相反,async.js和其他库处理“如果这些子任务中的任何一个失败,则失败”范例比典型的同步代码要好得多)
  • 优点:一些有趣且通常是艰巨的任务变得微不足道-例如获取正在执行的任务的状态,工作人员之间的通信或共享缓存状态
  • Pro:基于可靠的软件包管理器(npm)的庞大社区和大量优秀图书馆
  • 缺点:JavaScript没有标准库。您已经习惯于导入功能,以至于当您使用JSON.parse或不需要添加npm模块的其他内置方法时,感觉很奇怪。这意味着所有内容都有五个版本。如果您对默认实现不满意,那么即使Node.js“核心”中包含的模块也有五个变体。这导致快速发展,但也造成一定程度的混乱。

与简单的每个请求一个流程模型(LAMP):

  • 专业版:可扩展到数千个活动连接。非常快速和高效。对于Web机队,这可能意味着所需的盒子数量比PHP或Ruby减少了10倍
  • 优点:编写并行模式很容易。假设您需要从Memcached获取三个(或N个)blob 在PHP中执行此操作...您只是编写了先提取第一个Blob,然后提取第二个Blob,然后提取第三个Blob的代码?哇真慢 有一个特殊的PECL模块可以解决Memcached的特定问题,但是如果您想与数据库查询同时获取一些Memcached数据怎么办?在Node.js中,由于范例是异步的,因此让Web请求并行执行多项操作是很自然的。
  • 缺点:异步代码从根本上比同步代码复杂,并且如果开发人员缺乏对并发执行的实际含义的深入了解,那么前期学习曲线可能会很困难。不过,这比编写任何带锁的多线程代码要困难得多。
  • 缺点:如果一个计算密集型请求运行了例如100毫秒,它将使在同一Node.js进程中处理的其他请求的处理停顿……AKA,合作多任务可以使用Web Workers模式(分拆子流程来处理昂贵的任务)来缓解这种情况。另外,您可以使用大量的Node.js工作程序,并且只让每个人同时处理一个请求(由于没有进程回收,因此效率仍然很高)。
  • 缺点:运行生产系统比使用Apache + PHP,PerlRubyCGI模型要复杂得多。未处理的异常将使整个过程瘫痪,需要逻辑来重新启动失败的工作程序(请参阅cluster)。带有错误本机代码的模块可能会导致进程崩溃。每当工作人员死亡时,它正在处理的所有请求都将被丢弃,因此一个错误的API可能会轻易降低其他共同托管API的服务。

与用Java / C#/ C(“ C”是真的吗?)编写“真实”服务相对

  • 优点:在Node.js中执行异步操作比在其他任何地方执行线程安全操作都容易,并且可以提供更大的好处。到目前为止,Node.js是我工作过的最痛苦的异步范例。有了好的库,它只比编写同步代码难一点。
  • 优点:没有多线程/锁定错误。的确,您会先投入更多精力编写更详细的代码,这些代码表示没有阻塞操作的正确异步工作流。而且,您需要编写一些测试并使它正常工作(这是一种脚本语言,而且胖指法变量名仅在单元测试时捕获)。但是,一旦将其发挥作用,海森臭虫的表面积(奇怪的问题只会在一百万次运行中出现一次)就大大降低了。编写Node.js代码的工作量非常重于编码阶段。然后,您往往会得到稳定的代码。
  • 优点:JavaScript在表达功能方面要轻得多。很难用文字来证明这一点,但是JSON,动态类型,lambda表示法,原型继承,轻量级模块等等……表达相同的想法只需要较少的代码。
  • 骗子:也许您真的非常喜欢Java编码服务?

要获得关于JavaScript和Node.js的另一种观点,请查看从Java到Node.js,这是一篇有关Java开发人员的印象和学习Node.js经验的博客文章。


模块
在考虑节点时,请记住,您选择的JavaScript库将
定义您的体验。大多数人至少使用两个,一个异步模式帮助器(Step,Futures,Async)和一个JavaScript Sugar模块(Underscore.js)。

助手/ JavaScript Sugar:

  • Underscore.js-使用它。去做就对了。使用_.isString()和_.isArray()之类的东西,可以使您的代码更加美观和可读。我不太确定您是否可以编写安全的代码。另外,要增强命令行功能,请查看我自己的Underscore-CLI

异步模式模块:

  • 步骤 -一种非常优雅的方式来表示串行和并行动作的组合。我个人的建议。有关步骤代码的外观,请参阅我的文章
  • 期货 -通过需求表达订购的方式更加灵活(这真的是一件好事吗?)。可以表示“并行启动a,b,c。当A和B完成时,启动AB。当A和C完成时,启动AC”。这种灵活性需要格外小心,以避免工作流程中的错误(例如从不调用回调或多次调用)。请参阅Raynos的有关使用期货的文章(这是使我“获得”期货的文章)。
  • 异步 -更传统的库,每种模式只有一种方法。我从此开始,然后再宗教化为step并随后意识到,Async中的所有模式都可以用一个更具可读性的范例在Step中表达。
  • TameJS-由OKCupid编写的,它是一个预编译器,它添加了新的语言原始语“ await”以优雅地编写串行和并行工作流。该模式看起来很棒,但是它确实需要预编译。我仍在决定这一点。
  • StreamlineJS -TameJS的竞争对手。我倾向于驯服,但您可以下定决心。

或者要阅读有关异步库的所有内容,请参见作者的专访

网络框架:

  • 表达用于组织网站的Great Ruby on Rails-esk框架。它使用JADE作为XML / HTML模板引擎,这使构建HTML的痛苦减轻了很多,甚至变得优雅。
  • jQuery虽然从技术上讲不是节点模块,但jQuery迅速成为客户端用户界面的实际标准。jQuery提供了类似于CSS的选择器来“查询”可以随后操作的DOM元素集(集合处理程序,属性,样式等)。同样,Twitter的Bootstrap CSS框架,用于MVC模式的Backbone.jsBrowserify.js可以将所有JavaScript文件缝合到一个文件中。这些模块都已成为事实上的标准,因此如果您还没有听说过它们,则至少应将其检出。

测试:

  • JSHint-必须使用;我一开始没有使用它,现在似乎无法理解。JSLint重新添加了您使用Java之类的编译语言获得的许多基本验证。括号不匹配,未声明的变量,许多形状和大小的类型。您还可以启用各种形式的所谓的“肛门模式”,在其中可以验证空格的样式以及其他类似的样式,如果那是您的茶,就可以了-但真正的价值来自于获得有关确切行号的即时反馈,您忘记了结束“)” ...而不必运行代码并点击令人讨厌的行。“ JSHint”是Douglas CrockfordJSLint的更可配置的变体
  • 我开始偏爱Vows的Mocha竞争对手。两种框架都能很好地处理基础知识,但是复杂的模式在Mocha中往往更容易表达。
  • 誓言誓言真的很优雅。它会打印出一个可爱的报告(--spec),向您显示哪些测试用例通过/失败。花费30分钟学习它,您就可以轻松地为模块创建基本测试。
  • 僵尸 -无头测试HTML和JavaScript的使用JSDom作为一个虚拟的“浏览器”。非常强大的东西。将其与Replay结合使用可对浏览器内的代码进行快速的确定性测试。
  • 关于如何“思考”测试的评论:

    • 测试不是可选的。有了这样的JavaScript动态语言,也有少数的静态检查。例如,在执行代码之前,将两个参数传递给期望为4的方法不会中断。在JavaScript中创建错误的门槛很低。基本测试对于弥补使用编译语言的验证差距至关重要。
    • 忘记验证,只需执行代码即可。对于每种方法,我的第一个验证案例是“一切都没有中断”,这是最常触发的案例。证明您的代码运行时不会抛出80%的错误,这将极大地提高您的代码置信度,您会发现自己回过头来并添加了略过的验证案例。
    • 从小处着手,打破惯性障碍。我们都很懒惰,时间紧迫,很容易将测试视为“额外工作”。所以从小开始。编写测试用例0-加载模块并报告成功。如果您强迫自己这样做,那么测试的惯性障碍就被打破了。第一次(包括阅读文档)不到30分钟。现在编写测试用例1-调用您的方法之一,并验证“一切都没有中断”,也就是说,您没有收到错误。测试案例1应该花费您不到一分钟的时间。随着惯性的消失,逐渐扩大测试范围变得很容易。
    • 现在,用您的代码改进测试。不要被模拟服务器以及所有这些东西吓到了“正确的”端到端测试。代码从简单开始,不断发展以处理新情况。测试也应该如此。在为代码添加新案例和新复杂性时,请添加测试案例以执行新代码。当您发现错误时,添加验证和/或新案例以覆盖有缺陷的代码。当您正在调试并且对一段代码失去信心时,请返回并添加测试以证明它正在按照您的预期进行。捕获示例数据的字符串(从您调用的其他服务,您抓取的网站等),并将其提供给您的解析代码。这里有一些情况,那里的验证得到了改进,最终您将获得高度可靠的代码。

另外,查看推荐的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芯盒呢?

两种方式:

  1. 对于像图像编码这样的繁重的计算任务,Node.js可以启动子进程或将消息发送到其他工作进程。在此设计中,您将有一个线程管理事件流,并由N个进程执行繁重的计算任务,并消耗其他15个CPU。
  2. 为了扩展Web服务的吞吐量,您应该使用集群在一个盒子上运行多个Node.js服务器,每个内核运行一个(使用Node.js v0.6.x,此处链接的官方“集群”模块替换了具有不同的API)。然后,这些本地Node.js服务器可以在套接字上竞争以接受新连接,从而平衡它们之间的负载。接受连接后,它将紧密绑定到这些共享进程中的一个。从理论上讲,这听起来很糟糕,但在实践中,它的效果很好,可以避免编写线程安全代码的麻烦。同样,这意味着Node.js可以获得出色的CPU缓存亲和力,更有效地利用内存带宽。

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确实令人兴奋,这是我对库/平台的介绍...我发现它相当不错。

Node.js是为服务器端JavaScript代码构建的开源命令行工具。您可以下载tarball,编译并安装源代码。它使您可以运行JavaScript程序。

JavaScript由V8执行,V8是Google开发的JavaScript引擎,用于Chrome浏览器。它使用JavaScript API来访问网络和文件系统。

它因其性能和执行并行操作的能力而广受欢迎。

了解的node.js是最好的解释的node.js我迄今发现的。

以下是有关该主题的一些不错的文章。

闭包是在其创建的上下文中执行代码的一种方式。

为了确保一致性,您可以定义变量,然后启动非阻塞I / O函数,并将其发送给匿名函数以进行回调。

任务完成后,回调函数将在带有变量的上下文中执行,这就是闭包。

闭包之所以非常适合使用无阻塞I / O编写应用程序,是因为管理异步执行的函数的上下文非常容易。

关于如何管理模板以及如何对其进行逐步增强的两个很好的例子。您只需要一些轻量级的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浏览器。”

好吧,我明白

  • Node的目标是提供一种构建可伸缩网络程序的简便方法。
  • Node的设计与Ruby的Event Machine或Python的Twisted等系统相似,并受其影响。
  • V8 javascript的事件I / O。

对我来说,这意味着您在所有三个假设中都是正确的。图书馆看起来很有前途!

另外,别忘了提到Google的V8非常快。它实际上将JavaScript代码转换为具有与已编译二进制文件匹配的性能的机器代码。因此,与所有其他伟大的事物一起,它的速度非常快。

问:编程模型是事件驱动的,尤其是它处理I / O的方式

正确。它使用回调,因此任何访问文件系统的请求都将导致请求发送到文件系统,然后Node.js将开始处理其下一个请求。一旦从文件系统获得响应,它就只会担心I / O请求,这时它将运行回调代码。但是,可以发出同步I / O请求(即阻止请求)。由开发人员决定是在异步(回调)还是同步(等待)之间选择。

问:它使用JavaScript,解析器为V8。

问:可以轻松地用于创建并发服务器应用程序。

是的,尽管您需要手工编写很多JavaScript。最好看一下框架,例如http://www.easynodejs.com/,该框架随附完整的在线文档和示例应用程序。

本文地址:http://javascript.askforanswer.com/shenmeshinode-jsguanbi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!