Node.REDEME

30 阅读10分钟

Node是什么?

Node.js 是一个开源与跨平台的 JavaScript 运行时环境

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动非阻塞式 I/O的模型,使其轻量又高效。

Node.js 的包管理工具 npm 是全球最大的开源库生态系统。

可以理解为 Node.js 就是一个服务器端的、非阻塞式I/O的、事件驱动的JavaScript运行环境

优缺点

  • 处理高并发场景性能更佳
  • 适合I/O密集型应用,值的是应用在运行极限时,CPU占用率仍然比较低,大部分时间是在做 I/O硬盘内存读写操作

(因为Nodejs是单线程)

  • 不适合CPU密集型应用
  • 只支持单核CPU,不能充分利用CPU
  • 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃。程序运行不稳定,可能会出现服务不可用的情况
  • 程序运行效率较低,每秒的请求数维持在一个较低的水平

组成

在 Node.js 里运行 JavaScript,跟在 Chrome 里运行 JavaScript 有什么不同?二者采用的是同样的 JS 引擎。

在 Node.js 里写 JS,和在前端写 JS,几乎没有不同。在写法上的区别在于:Node.js 没有浏览器、页面标签相关的 API,但是新增了一些 Node.js 相关的 API。

  • Node.js中不能使用BOM和DOM的API
  • Node.js中的顶级对象为global而不是window,也可以用globalThis访问顶级对象

通俗来说,对于开发者而言,在前端写 JS 是用于控制浏览器;而 Node.js 环境写 JS 可以控制整个计算机。

JavaScript 的组成

我们知道,JavaScript 的组成分为三个部分:

  • ECMAScript
  • DOM:标签元素相关的API
  • BOM:浏览器相关的API

ECMAScript 是 JS 的语法;DOM 和 BOM 浏览器端为 JS 提供的 API。

Node.js 的组成

而 Node.js 的组成分为:

  • ECMAScript。ECMAScript 的所有语法在 Node 环境中都可以使用。
  • Node 环境提供的一些附加 API(包括文件、网络等相关的 API)。

image.png

应用场景

它被广泛地应用在 Web 服务、开发工作流、客户端应用等诸多领域。其中,在 Web 服务领域,业界对 Node.js 的接受程度最高。

BFF 中间层

BFF,即 Backend For Frontend(服务于前端的后端)。玉伯在《从前端技术进化到体验科技open in new window》这篇文章中点出了 BFF 层的概念:

BFF 模式下,整体分工很清晰,后端通过 Java/C++ 等语言负责服务实现,理想情况下给前端提供的是基于领域模型的 RPC 接口,前端则在 BFF 层直接调用服务端 RPC 接口拿到数据,按需加工消费数据,并实现人机交互。

基于 BFF 模式的研发,很适合拥有前端技术背景的全栈型工程师。这种模式的好处很明显,后端可以专注于业务领域,更多从领域模型的视角去思考问题,页面视角的数据则交给前端型全栈工程师去搞定。领域模型与页面数据是两种思维模式,通过 BFF 可以很好地解耦开,让彼此更专业高效

在 Web 服务里,搭建一个中间层,前端访问中间层的接口,中间层再访问后台的 Java/C++ 服务。这类服务的特点是不需要太强的服务器运算能力,但对程序的灵活性有较高的要求。这两个特点,正好和 Node.js 的优势相吻合。Node.js 非常适合用来做 BFF 层,优势如下:

  • 对前端来说:让前端有能力自由组装后台数据,这样可以减少大量的业务沟通成本,加快业务的迭代速度;并且,前端同学能够自主决定与后台的通讯方式。
  • 对后台和运维来说,好处是:安全性(不会把主服务器暴露在外面)、降低主服务器的复杂度等。

服务端渲染

客户端渲染

客户端渲染 (CSR / Client side render):前端通过一大堆接口请求数据,然后通过 JS 动态处理和生成页面结构和展示

优点是前后端分离、减小服务器压力、局部刷新。

缺点是不利于 SEO(如果你的页面然后通过 Ajax 异步获取内容,抓取工具并不会等待异步完成后再行抓取页面内容)、首屏渲染慢

服务端渲染

服务端渲染 (SSR / Server Side Render):服务器返回的不是接口数据,而是一整个页面(或整个楼层)的 HTML 字符串,浏览器直接显示即可

也就是说,在服务器端直接就渲染好了,然后一次性打包返回给前端。优点是有利于 SEO、首屏渲染很快

总结: 搜索引擎优化 + 首屏速度优化 = 服务端渲染

备注:这里的「服务端渲染」只是让 Node.js 做中间层,不会替代后端的,后台同学请放心。

参考链接:

历史回顾:

  1. 一开始,页面很简单,html 是后端渲染的(比如PHP、ASP、JSP等方式)。后端发现页面中的 js 好麻烦(虽然简单,但是坑多),于是让公司招聘专门写 js 的人,简称「前端切图仔」。
  2. 随着 Node.js 和前端 MVC 的兴起,以及前端越来越复杂,慢慢演变成了「前后端分离」。
  3. 前端的 SPA 应用流行之后,发现 SEO 问题很大,而且首屏渲染速度很慢,但是自己选的路再难走也要走下去,于是用 Node.js 在服务端渲染被看成是一条出路。
  4. 以前在一起的时候,是后端做部分前端的工作;现在在一起的时候,是前端做部分后端的工作。

小型后端

Node可以用来做小型服务、小型网站的后端(基于 Express、Koa 框架)。

现在很多公司的后台管理系统,都是用 Node.js 来开发接口,毕竟,后台管理系统对性能和并发的要求不是太高。

有了 Node.js 之后,通过 JS 直接操作 DB,做增删改查,生成接口,极大降低了前端同学的学习门槛。

当然,有时候做 Node.js 开发,是因为:后台人力不够,所以把后台开发的一部分工作量,转移给前端同学。

项目构建工具

前端正在广泛使用的构建工具 gulp、Webpack,就是基于 Node.js 来实现的。

PC客户端软件

Node可以用来做 PC 客户端软件(基于 Electron 框架),Electron 框架就是基于 Node.js 的,可以用来开发客户端软件。

Electron

Electron 原名为 Atom Shell,是由 GitHub 开发的一个开源框架。Electron 以 Node.js 作为运行时(runtime),以 chromium 作为渲染引擎,使开发者可以使用 JS 这种前端技术栈开来发跨平台的桌面GUI应用程序。

有一点你可能会感到惊讶:程序员们都在用的代码编辑器 VS Code 软件, 就是基于 Electron 框架来开发的。其他使用 Electron 进行开发的知名应用还有:Skype、GitHub Desktop、Slack、WhatsApp等。

还有一个例子是:电子游戏直播网站 Twitch,号称是国外游戏直播的鼻祖,它在 PC 端的客户端软件,就是用 Electron 框架的。你会发现,Twitch 的网站视觉,和 PC 端的视觉,几乎是一样的。如果两端都采用 JS 语言,就可以极大的复用现有的工程。

小结

短期来看,Node.js 很难像 Java/C++ 那样,成为后台的主力开发语言。这并非是因为 Node.js 的性能问题,主要是因为,Node.js 还比较年轻,经验积累太少,框架的支持度不够。搞企业级服务,Node.js 敌不过 Java/C++,所以目前只能搞「轻量级」;但未来可期。

限制语言能力的不是语言本身,而是生态。

知识支撑

非阻塞式 I/O

非阻塞式 I/O 是一种 I/O 模型,它允许应用程序在执行 I/O 操作时继续执行其他操作,而不必等待 I/O 操作完成。在

非阻塞式 I/O 模型中,当应用程序发起一个 I/O 操作时,它会立即返回,而不会等待 I/O 操作完成。当 I/O 操作完成时,操作系统会通知应用程序,应用程序再去处理已完成的数据。

阻塞式 I/O

相比之下,阻塞式 I/O 模型是一种传统的 I/O 模型,当应用程序执行 I/O 操作时,它会一直等待 I/O 操作完成,直到数据可用或超时。这种模型会导致应用程序的性能受到限制,因为在等待 I/O 操作完成期间,应用程序无法执行其他操作。

Node.js 使用非阻塞式 I/O 模型,这使得它能够在执行 I/O 操作时继续执行其他操作,从而提高了应用程序的性能和吞吐量。

Node.js 在 I/O 操作完成时使用回调函数来处理已完成的数据,这使得应用程序的代码更加简洁和易于维护。

此外,Node.js 还提供了event loop机制来管理 I/O 操作,这使得它能够处理大量的并发请求,并且可以轻松地进行水平扩展。

事件驱动

事件驱动就是当进来一个新的请求的时,请求将会被压入一个事件队列中,然后通过一个循环来检测队列中的事件状态变化,如果检测到有状态变化的事件,那么就执行该事件对应的处理代码,一般都是回调函数

比如读取一个文件,文件读取完毕后,就会触发对应的状态,然后通过对应的回调函数来进行处理

image.png

CPU密集型

CPU 密集型任务是指需要大量使用 CPU 计算能力的任务,其计算量通常较大。

这种任务通常需要进行大量的数学运算、图像处理、语音识别、数据分析等操作,需要占用大量的 CPU 时间。

举几个例子:

  • 图像处理:图像处理通常需要对图像进行多次计算,如滤波、模糊、锐化等操作,这些操作需要大量的 CPU 计算能力。
  • 数据分析:对于大量数据的分析和处理,例如机器学习、人工智能等任务,通常需要进行大量的计算,这些计算需要占用大量的 CPU 时间。
  • 加密解密:加密和解密操作需要进行大量的数学计算,这些计算需要占用大量的 CPU 时间。
  • 压缩解压缩:压缩和解压缩操作需要进行大量的计算,这些计算需要占用大量的 CPU 时间。

在这些情况下,使用 Node.js 可能会受到性能瓶颈的限制,因为 Node.js 是单线程的,如果处理 CPU 密集型任务,则可能会占用整个 CPU,导致其他请求无法得到处理。相比之下,使用支持多线程的语言和框架,如 Java 或 Python,可能更适合处理这些任务。

知名度较高的 Node.js 开源项目

  • express:Node.js 中著名的 web 服务框架。
  • Koa:下一代的 Node.js 的 Web 服务框架。所谓的“下一代”是相对于 Express 而言的。
  • Egg:2016 年,阿里巴巴研发了知名的 Egg.js 开源项目,号称企业级 Web 服务框架。Egg.js 是基于 Koa 开发的。
  • mocha:是现在最流行的 JavaScript 测试框架,在浏览器和 Node 环境都可以使用。
  • PM2:node 多进程管理。
  • jade:非常优秀的模板引擎,不仅限于 js 语言。
  • CoffeeScript:用简洁的方式展示 JavaScript 优秀的部分。
  • Atom:编辑器。
  • VS Code:最酷炫的编辑器。
  • socket.io:实时通信框架。


最后一句
学习心得!若有不正,还望斧正。