作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
托米斯拉夫·卡潘的头像

Tomislav Capan

Tomislav是AWS认证解决方案架构师, developer, 并拥有10年以上的技术顾问经验. 托米斯拉夫拥有计算机硕士学位.

Previously At

Deliveroo
Share

编者注:本文的英文版由我们的编辑团队于2022年3月10日更新. 它已被修改,以包括最近的来源,并与我们目前的编辑标准保持一致.

JavaScript的流行带来了很多变化. 我们现在在网络上做的事情在几年前是很难想象的.

在我们深入研究之前 Node.js(“Node”)解决方案,考虑申请 跨栈的JavaScript 统一语言和数据格式(JSON),将有利于开发人员资源的最佳重用. 因为这是JavaScript比Node更多的好处.具体来说,我们就不详细说明了.

具有所有优点的Node.Js在许多依赖其独特优势的知名公司的技术堆栈中发挥着关键作用. This Node.js教程将介绍如何实现这些优势,以及为什么可以(或不可以)使用Node.js.

What Is Node.js?

Node.js由Google的V8 JavaScript引擎组成, libUV平台抽象层, 以及一个用JavaScript编写的核心库. 此外,节点.js基于开放web栈(HTML, CSS和js),并在标准端口80上运行.

Node.Js为开发人员提供了一个全面的非阻塞工具, 事件驱动的I/O范式. Ryan Dahl, Node的创造者.js“受到Gmail等应用程序的启发”,然后创建了Node.js旨在创建具有推送功能的实时网站.

在基于无状态请求-响应范式的无状态web发展了20多年之后, 我们终于有了实时的web应用程序, 双向连接.

Why Use Node.js?

Node.js在WebSocket上采用推送技术的实时web应用中大放异彩. 在基于无状态请求-响应范式的无状态web发展了20多年之后, 我们终于有了实时的web应用程序, 双向连接, 客户机和服务器都可以发起通信的地方, 允许他们更自由地交换数据. 这与典型的web响应范式形成鲜明对比, 客户端总是发起通信.

有人可能会说,我们多年来一直以Flash和Java applet的形式使用这项技术. In reality, however, 这些都是沙盒环境,使用web作为传输协议来传递给客户端. Plus, Flash和Java applet是独立运行的,经常在非标准端口上运行, 哪些可能需要额外的权限.

How Does Node.js Work?

Node在构建快速、可扩展的网络应用程序方面非常出色. 这是由于它能够以高吞吐量处理大量并发连接.

Node.Js使用非阻塞, 事件驱动的I/O,以便在面对跨分布式设备运行的数据密集型实时应用程序时保持轻量级和高效.

Node.Js是一个满足特定需求的平台,理解这一点是绝对必要的. 例如,您不会使用Node.js来执行cpu密集型操作. 如果将Node用于繁重的计算,那么它几乎所有的优点都将失效.

Node.Js是一个满足特定需求的平台. It is not 一个银弹,或者一个将主宰web开发世界的平台.

How Node.Js的工作原理很有趣. 与传统的web服务技术相比,每个连接(请求)都会产生一个新线程(占用系统RAM并最终达到可用RAM的最大值)。, Node.js在单线程上运行,使用非阻塞I/O调用. 这允许Node在事件循环中支持成千上万的并发连接.

Traditional vs. Node.js服务器线程

根据Michael Abernethy 2011年的文章 这就是Node.js?”, 以一个带有2 MB内存的线程为例, 运行在具有8gb RAM的系统上, 理论最大值为4,000个并发连接. 再加上…的成本 线程之间的上下文切换,您将得到传统web服务技术中的常见场景. Node.Js避免了这一切,实现了高可伸缩性.

There is, of course, 在所有客户端请求之间共享单个线程的问题, 潜在的陷阱 writing Node.js应用程序.

First, 繁重的计算可能会阻塞Node的单线程,并导致所有客户端出现问题, 因为传入的请求被阻塞,直到所述计算完成.

Second, 开发人员需要保持警惕,防止异常冒泡到核心(顶部)节点.因为这会导致Node . js事件循环.终止Js实例,有效地使程序崩溃.

防止异常流, 我们将错误作为回调参数传递给调用者(而不是“抛出”),“就像我们在其他环境中做的那样。”. 如果出现了未处理的异常,则可以使用 Forever 模块或外部工具,如 暴发户和监控 and just upstart 监控节点.Js进程并执行必要的 恢复崩溃的实例. 请注意,这些工具不处理用户会话当前状态的恢复.

npm:节点包管理器

内置支持 使用NPM进行包管理 包含在每个Node中.js安装. npm模块背后的思想与 Ruby Gems:它是一组公开可用的, 可重用组件, 通过在线存储库轻松安装, 使用版本和依赖管理.

npm Inc. 共享一个打包模块的列表,这些模块也可以通过它的npm CLI工具访问. 模块生态系统向所有人开放,以发布他们自己的模块, 哪些将被添加到NPM存储库中.

一些有用的npm模块包括:

express, Express.js,或者简单的Express

一个受sinatra启发的用于Node的web开发框架.js, and the de facto 大多数Node的标准.js应用程序.

hapi

一个模块化和简单易用的以配置为中心的框架,用于构建web和服务应用程序.

connect

一个用于Node的可扩展HTTP服务器框架.Js,提供了一系列高性能的插件 middleware; serves as a base foundation for Express.

socket.io and sockjs

两个常见WebSocket组件的服务器端组件.

pug (原玉)

受HAML启发的模板引擎,这是Express中的默认值.js.

mongodb and mongojs

MongoDB包装器为Node中的MongoDB对象数据库提供API.js.

redis

Redis客户端库.

虚线,下划线,懒惰.js

JavaScript实用工具带. Underscore发起了游戏,但被两个对手之一推翻了,主要是由于懒惰.js' 更好的性能 模块化实现.

forever

A utility for ensuring that a given node script runs continuously; keeps your Node.面对任何意外的故障,Js进程将在生产中启动.

bluebird

一个功能齐全的Promises/A+实现,具有非常好的性能.

moment.js

一个JavaScript日期库,用于解析、验证、操作和格式化日期.

在哪里使用节点.js

Chat

聊天是一种典型的实时, 多用户应用程序——从以前的IRC到Node中的现代实现.js with WebSocket.

聊天应用程序是轻量级的、高流量的和数据密集型的(但是低处理量) /computation). 它跨分布式设备运行,是Node的最佳示例.js.

简单,但涵盖了您将在典型Node中使用的大多数范例.Js应用程序,聊天是一个很好的学习用例.

让我们来描述一下聊天是如何工作的:假设我们有一个单独的聊天室,其中用户可以以一对多(实际上是全部)的方式交换消息. 我们还假设有三个用户连接到我们的留言板.

在服务器端,一个简单的Express.Js应用程序实现:

  1. A GET / 请求处理程序,它提供包含留言板和初始化新消息输入的“发送”按钮的网页, and
  2. 监听WebSocket客户端发出的新消息的WebSocket服务器.

在客户端,我们有一个HTML页面,设置了几个处理程序:

  1. ' Send '按钮单击事件的处理程序, 它接收输入消息并将其发送到WebSocket.
  2. 在WebSocket客户端上监听新传入消息的处理程序.e.(服务器希望客户端显示的用户源消息).

当客户端发布消息时,会发生以下情况:

  1. 浏览器通过JavaScript处理程序捕获“Send”按钮点击. 它从输入字段(i.e., 消息文本), 并使用连接到服务器的WebSocket客户端发送WebSocket消息(在网页初始化时初始化).
  2. WebSocket连接的服务器端组件接收消息并将其转发给所有其他连接的客户端, 使用广播方法.
  3. 所有客户端都以推送消息的形式接收新消息, 通过在网页中运行的WebSocket客户端组件. 然后,客户端获取消息内容并就地更新网页, 通过将新消息附加到公告板上.

节点中的客户端和服务器WebSockets.js Application

Here is a 用NodeJS实时聊天的简单例子,Socket.io和ExpressJS.

对于一个更强大的解决方案,你可以使用一个基于Redis存储的简单缓存. 或者在更高级的解决方案中, 使用消息队列处理到客户机的消息路由, 以及更强大的传递机制. 队列可以弥补暂时的连接丢失,或者在已注册的客户端脱机时存储消息.

无论您选择哪种解决方案,Node.Js在相同的基本原则下运行:对事件作出反应, 处理多个并发连接, 保持用户体验的流动性.

在对象数据库之上的API

Node.js非常适合从对象数据库(例如.g., MongoDB). json存储的数据允许Node.Js功能无阻抗失配和数据转换.

例如,如果你在使用 Rails, 将JSON转换为二进制模型, 然后当数据被Backbone使用时,通过HTTP将它们以JSON形式公开.js, Angular.js, etc.-甚至是普通的jQuery AJAX调用. With Node.. js中,你可以使用 REST API 供客户端消费.

如果您正在使用MongoDB, 在从数据库读取或写入数据时,您不必担心在JSON和其他数据之间进行转换. Thus, 通过在客户机上使用统一的数据序列化格式,可以避免多次转换的需要, server, and database.

Queued Inputs

Node允许您灵活地将数据库注销推到一边. 但是使用Node还有更多的理由.js.

如果您正在接收大量并发数据,那么您的数据库可能会成为瓶颈. Node.Js可以很容易地处理并发连接. 因为(在这种情况下)数据库访问是一个阻塞操作,所以我们遇到了麻烦. 解决方案是在数据真正写入数据库之前确认客户端的行为.

这种方法使系统能够在高负载下保持响应能力. 当客户端不需要对成功的数据写入进行确认时,它特别有用, 当记录或写入用户跟踪数据时, 分批加工, 留待以后使用, or for 不需要立即反映的操作比如更新Facebook上的“喜欢”计数.

数据通过某种缓存或消息队列基础设施进行排队 RabbitMQ or ZeroMQ. 然后由单独的数据库批写进程或计算密集型处理后端服务对其进行消化, 用性能更好的平台编写.

在Node中批量写入数据库.js与消息队列.

简而言之:使用Node,您可以将数据库写入推到一边,稍后再处理.

数据流

为什么不用Node呢?.数据流中的Js? 在更传统的网络平台上, HTTP请求和响应被视为孤立的事件——尽管它们实际上是流. 我们可以利用这种观察来构建一些很酷的Node.js features.

例如,我们可以在文件还在上传的时候处理它们. 当数据通过流进入时,我们可以在上传过程中并行处理它. 这是对的 实时音频或视频编码 以及各种数据源之间的代理.

Proxy

Node.Js很容易被用作服务器端代理, 它可以以非阻塞的方式处理大量的同时连接吗. 这对于代理具有不同响应时间的不同服务非常有用, 或者从多个源点收集数据.

As an example, 让我们考虑一个与第三方资源通信的服务器端应用程序, 从不同的来源提取数据, 或者将资产(如图像和视频)存储到第三方云服务.

如果您的代理基础设施不存在,使用Node代替专用代理服务器可能会有所帮助, 或者如果你需要一个本地发展的解决方案. 我的意思是,您可以使用Node构建客户端应用程序.用于资产和代理/存根API请求的js开发服务器. 在生产环境中,您将使用专用代理服务(如nginx或HAProxy)处理此类交互。.

经纪/股票交易员的仪表盘

在应用程序级别, 经纪商的交易软件是桌面软件占主导地位的另一个例子, 但可以很容易地被实时网络解决方案所取代. 经纪人的交易软件跟踪股价, 进行计算和技术分析, 并呈现图形和图表.

为什么不用Node呢?.为经纪人编写一个实时的基于web的解决方案? 然后,经纪人可以很容易地切换工作站或工作地点. 我们可能很快就会在佛罗里达、伊比沙岛或巴厘岛的海滩上见到我们的经纪人.

应用程序监控仪表板

想象一下,如果你能实时看到你的访问者在做什么,你将如何发展你的业务. 使用Node的实时双向套接字,您可以获得这种能力.

带有WebSocket的Node非常适合跟踪网站访问者并实时可视化他们的交互.

使用Node的原因.用于监控仪表板的Js包括收集来自用户的实时统计数据, 或者通过在漏斗的特定点打开沟通渠道,与访问者进行有针对性的互动. CANDDi 将这个想法产品化.

系统监控仪表板

现在,让我们来看看基础设施方面. Imagine, for example, 希望为用户提供服务监视页面的SaaS提供商, 比如GitHub的状态页面. With Node.在Js的事件循环中,我们可以创建一个强大的基于web的仪表板来检查服务的状态 asynchronous 方式,使用WebSocket向客户端推送数据.

使用这种技术,内部(公司内部)和公共服务的状态都可以实时报告. 再往前推一点,试着想象一下 网络运营中心 它监视电信运营商的应用程序, 云/网络/主机提供商, 或者一些金融机构. 这些应用程序将运行在由Node支持的开放web堆栈上.js和WebSocket.

不要尝试在Node中构建硬实时系统.e.(需要一致响应时间的系统). Erlang is probably a better choice for that class of application.

在哪里使用节点.但要谨慎。

服务器端Web应用程序

With Node.js with Express.Js,您可以在服务器端创建经典的web应用程序. 在可能的情况下,这种请求-响应范式中Node.js将携带渲染的HTML不是一个理想的用例. 支持和反对这种方法的理由都有. 以下是一些需要考虑的事实:

Pros:

  • 您可以大大简化不需要cpu密集型计算的应用程序的开发, 通过使用Javascript从上到下构建它, 甚至下到数据库级别—如果您使用JSON存储对象DB (e.g., MongoDB).
  • 爬虫接收一个完全呈现的HTML响应, 哪一个更SEO友好, say, 运行在Node之上的单页应用程序或WebSocket应用程序.js.

Cons:

  • 任何cpu密集型计算都会阻塞Node.Js的响应性,所以线程平台是更好的方法. 或者,您可以尝试扩展计算.
  • Using Node.使用关系数据库的Js可能会很痛苦. 如果你想执行关系运算, 考虑使用Rails这样的环境, Django, or ASP.Net MVC.

cpu密集型计算的另一种替代方法是创建一个具有后端处理的高度可伸缩mq支持的环境,以使Node作为前端“职员”异步处理客户机请求.

哪里不使用节点.js

在某些情况下,Node可能不是完成任务的最佳工具.

带有关系数据库应用程序的服务器端Web应用程序

Ruby on Rails曾经是访问关系数据库(如PostgreSQL)的明确选择, MySQL, 和Microsoft SQL Server. 这是因为Node的关系DB工具.j还处于早期阶段,而, in contrast, Rails自动提供开箱即用的数据访问设置, 以及DB模式迁移支持工具, 和其他宝石(双关语). Rails及其对等框架具有成熟且经过验证的Active Record或Data Mapper数据访问层实现.

只在前端使用Node是可能的,而且并不罕见, 同时保持您的Rails后端可以轻松访问关系数据库.

但是情况已经改变了. Sequelize, TypeORM, and Bookshelf 在成为成熟的ORM解决方案方面已经走了很长一段路. 它可能也值得一看 Join Monster 如果您希望从GraphQL查询生成SQL.

繁重的服务器端计算和/或处理

Node.Js并不是处理繁重计算的最佳平台. 不,您肯定不想在Node中构建斐波那契计算服务器.js.

In general, 任何cpu密集型操作都会使Node通过其事件驱动提供的吞吐量优势失效, 非阻塞I/O模型. 这是因为当线程忙于处理数字时,传入的请求会被阻塞——假设您试图在用于响应请求的同一个Node实例中运行计算.

Since Node.js是单线程的,只使用一个CPU核心, 这将需要相当大的努力来发展 集群模块 为了在多核服务器上提供并发性. 或者,您可以运行多个Node.Js服务器实例非常容易 通过nginx反向代理.

使用集群,您仍然应该将所有繁重的计算任务卸载到后台进程. 确保为后台进程使用合适的环境, 并且它们通过RabbitMQ之类的消息队列服务器进行通信.

虽然您可以在主服务器上运行后台进程, 一旦负载增加,这种方法可能无法很好地扩展. 您可以将后台处理服务分发到单独的工作服务器,而无需配置前端web服务器的负载.

With Node.与大多数其他平台相反,js可以享受我们谈到的高请求/秒吞吐量, 因为每个请求都是Node快速有效地处理的小任务.

为什么选择节点.js?

我们讨论过Node.Js从理论到实践,从它的目的开始,到它的最佳点和陷阱结束.

Node的问题几乎总是源于这样一个事实 阻塞操作是万恶之源99%的Node误用都是直接后果.

在Node中,阻塞操作是万恶之源——99%的Node误用都是其直接后果.

如果您的用例不包含cpu密集型操作, Nor访问阻塞资源, 您可以利用Node的优势.并享受快速和可扩展的网络应用程序. 欢迎来到实时网络.

了解基本知识

  • What is Node.js?

    Node.js是一个服务器端、开源的JavaScript运行时环境. Node使用Google的V8引擎- libuv来提供跨平台兼容性和一个核心库. Notably, Node.Js不公开全局窗口对象,因为它不在浏览器中运行.

  • What is Node.js used for?

    Because Node.Js是单线程的,我们主要将它用于非阻塞的、事件驱动的服务器. 我们也可以使用Node.用于传统网站和后端API服务, 因为它是实时设计的, 记住基于推送的架构.

  • 什么是web框架?

    像Angular和React这样的Web框架是帮助组织和生成在Web浏览器中运行的前端代码的库. Web框架为公共操作重用代码,从而减少了开发时间. 有些web框架是全栈的.

  • Is Node.js a framework?

    No, Node.Js是一个环境. 后端框架在Node中运行.js. 流行的、兼容的框架包括Express.js(也称为Express)用于HTTP服务器和Socket.WebSocket服务器的IO.

  • Is Node.Js是一种编程语言?

    Node.Js不是一门编程语言. The “.JavaScript在其名称末尾表示JavaScript是与其相关的编程语言. 任何可以翻译成javascript的TypeScript, Haxe, 或coffeescript—也可以与Node一起使用.js.

  • Why is Node.js popular?

    除了非常有效之外,Node.js之所以受欢迎,是因为它庞大、活跃、开源、基于javascript的生态系统.

  • Node和Node之间的区别是什么.js和Angular/AngularJS?

    The Node.js运行时环境在服务器上执行JavaScript代码, 而Angular是一个在客户端执行的JavaScript框架.e.,在网页浏览器内).

  • Why is Node.js bad?

    Node.js isn’t bad. 它的技术被广泛应用于许多类型的服务器. 然而,由于它是单线程的,Node.Js对于兼作计算服务器的web服务器来说并不理想——如此繁重的计算会阻碍服务器的响应.

聘请Toptal这方面的专家.
Hire Now
托米斯拉夫·卡潘的头像
Tomislav Capan

Located in 克罗地亚的萨格勒布

Member since 2013年2月20日

作者简介

Tomislav是AWS认证解决方案架构师, developer, 并拥有10年以上的技术顾问经验. 托米斯拉夫拥有计算机硕士学位.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Previously At

Deliveroo

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

加入总冠军® community.