Node.js 基本架构解析

简介: Node.js 基本架构解析

1、Node.js 简介

       Node.js 最初开始于 2009 年,是一个可以让 JavaScript 代码离开浏览器的执行环境也可以执行的项目。 它不是一个前端的 web 框架,不能将其与 Java 的 Spring 做类比;同时它也不是一门编程语言,它并不是面向后端的一门 js,它仅仅是以 js 为后缀的,所以也不能将其与 Python 或 PHP 做对比。那 Node.js 是什么?


       我们一般称 Node.js 是一个平台,它将多种技术组合起来,让 JavaScript 也能调用系统接口、或进行后端开发的应用。Node.js 依赖的架构主要有 V8 引擎 和 libuv,以及一些 C/C++ 实现的 c-ares、http-parser、OpenSSL、zlib。


       说白话就是,Node.js 给 JavaScript 提供了一个平台,让 JavaScript 可以调用一些 C/C++ 的接口,这大大扩展了 JavaScript 的能力,进而使 JavaScript 有了后端开发的能力。以下是 Node.js 的工作流程:

       ps:Node.js 的版本 已经到 15 了,双数是稳定版,单数是非稳定版,Node 8 可能不太支持 Vue3,建议使用 Node 10 或 12。至于 Node.js 的安装,可以到 Node 官网 直接下载安装包,傻瓜式安装就行了,安装完毕之后在命令行输入 node -v 后,如果能显示当前版本即表示安装成功。

2、Node.js 基本架构

       Node.js 主要有 Node Standard Library、Node Bindings、V8、Libuv 四部分,架构图如下:

Node Standard Library 是 Node 专门提供给开发人员使用的标准库,如 Http,fs 等模块。


Node Bindings 是沟通 JS 和 C++ 的桥梁,封装 V8 引擎 和 Libuv 的细节,向上层提供基础 API 服务。


第三层是支撑 Node.js 运行的关键,由 C/C++ 实现。


V8 是 Google 开发的 JavaScript 引擎,提供 JavaScript 运行环境,可以说它就是 Node.js 的发动机。


Libuv 是专门为 Node.js 开发的一个封装库,提供跨平台的异步 I/O 能力.


C-ares:提供了异步处理 DNS 相关的能力。


http_parser、OpenSSL、zlib 等:提供包括 http 解析、SSL、数据压缩等其他的能力。

3、Node bindings 是个啥?

       Node Bindings 是沟通 JS 和 C++ 的桥梁,封装 V8 引擎 和 Libuv 的细节,向上层提供基础 API 服务。


       举个例子:C/C++ 实现了一个 http_parser 的库,非常高效,但是前端开发人员只会写 JavaScript,直接调用这个库肯定是不能成功的,所以就需要一个中间的桥梁。于是 Node.js 的作者就用 C++ 对 http_parser 库进行封装,使它符合某些要求(比如统一数据类型等),封装的文件叫做 http_parser_bindings.cpp。同时 Node.js 提供的编译工具可以将其编译为.node文件。这样 JavaScript 代码可以直接 require 这个 .node 文件,这样 JavaScript 就能调用 C++ 库。


       中间的桥梁就是 binding,由于 Node.js 提供了很多 binding,多个 binding 就构成了 Node 基本架构中的 Node bindings 了。有了这个 Node Bindings 后,JavaScript 和 C++ 就可以进行一些相互调用的操作,进而实现功能上的一些通信。这里有官网提供的示例,便于大家理解 JS 和 C++ 是如何进行通信的:JS 调用 C++ 代码、C++ 调用 JS 回调。


       ps:除了 Node.js 提供的这些 Bindings 之外,还支持开发人员自定义封装 C/C++ 来扩展你想要实现的功能。

4、为什么是 libuv?

       Node.js 最早时是使用了 Google 的 V8 解析引擎 和 Marc Lehmann 的 libev。Node.js 将事件驱动的 I/O 模型与适合该模型的编程语言(JavaScript)融合在了一起,但随着 Node.js 的日益流行,Node.js 也需要同时支持 Windows,但是 libev 只能在 Unix 环境下运行,而在 Windows 系统平台上与 kqueue(FreeBSD) 或者 (e)poll(Linux) 等内核事件通知相应的机制是 IOCP。


       基于上述背景,Node.js 之父 Ryan 就着手开发了一个 跨平台的异步 I/O 库,将上述操作系统对应的库都整合到一起,于是乎就诞生了 libuv,libuv 会根据不同的操作系统自动选择合适的方案,它的所有功能都是异步的,一般是用于 操作TCP/UDP/DNS/文件等的异步操作。


       为啥是异步?因为即便是 SSD 的访问相较于高速的 CPU,仍然是慢速设备。于是基于 事件驱动 的 IO 模型就应运而生,解决了高速设备同步等待慢速设备或访问的问题。这不是 libuv 的独创,linux kernel 原生支持的 NIO也是这个思路。 但 libuv 统一了网络访问,文件访问,做到了跨平台。

       上述 libuv 的架构图中,从左往右分为两部分,一部分是与网络I/O相关的请求,而另外一部分是由文件I/O, DNS Ops以及User code组成的请求。


       从图中可以看出,对于Network I/O和以File I/O为代表的另一类请求,异步处理的底层支撑机制是完全不一样的。对于Network I/O 相关的请求, 根据 OS 平台不同,分别使用 Linux 上的 epoll,OSX 和 BSD 类 OS 上 的 kqueue,SunOS 上的event ports 以及 Windows 上的 IOCP 机制。而对于 File I/O 为代表的请求,则使用 thread pool。利用 thread pool 的方式实现异步请求处理,在各类 OS 上都能获得很好的支持。

5、V8 引擎又是啥?

       V8 是目前商用的执行 JavaScript 最快的一个引擎,它的功能有很多:将 JavaScript 源代码变成本地代码并执行、维护 JavaScript 的调用栈,确保 JavaScript 函数的执行顺序、负责内存管理,为所有对象分配内存、垃圾回收,重复利用无用的内存、实现JS的标准库。

       现在 JS 引擎的执行过程大致是:源代码 --->抽象语法树 --->字节码 --->JIT--->本地代码。


       V8 更加直接的将抽象语法树通过 JIT 技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。 在 V8 生成本地代码后,也会通过 Profiler 采集一些信息,来优化本地代码。虽然,少了生成字节码这一阶段的性能优化, 但极大减少了转换时间。


       这里有几个注意的点:V8 是不提供 DOM API 的,那是浏览器所提供的、V8 本身是包含多个线程的,但它执行 JS 的过程是单线程的、V8 自己自带了 Eventloop,但是 Node.js 基于 libuv 自己做了一个。

目录
相关文章
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
628 3
|
9月前
|
JavaScript 前端开发 IDE
TypeScript vs. JavaScript:技术对比与核心差异解析
TypeScript 作为 JavaScript 的超集,通过静态类型系统、编译时错误检测和强大的工具链支持,显著提升代码质量与可维护性,尤其适用于中大型项目和团队协作。相较之下,JavaScript 更灵活,适合快速原型开发。本文从类型系统、错误检测、工具支持等多维度对比两者差异,并提供技术选型建议,助力开发者合理选择。
1576 1
|
9月前
|
JavaScript 前端开发 开发者
Nest.js控制器深度解析:路由与请求处理的高级特性
以上就是对 NestJS 控制层高级特性深度解析:从基本概念到异步支持再到更复杂场景下拦截其与管道等功能性组件运用都有所涉及,希望能够帮助开发者更好地理解和运用 NestJS 进行高效开发工作。
490 15
|
9月前
|
存储 JavaScript 前端开发
JavaScript 语法全面解析
JavaScript 语法体系丰富且不断更新,从基础的变量声明、数据类型,到复杂的函数、对象、异步语法,每个知识点都需要开发者深入理解并灵活运用。本文梳理的 JS 语法核心内容,可为开发者提供系统的学习框架,后续还需通过大量实践(如编写交互组件、实现业务逻辑)巩固知识,逐步提升 JS 编程能力,应对前端开发中的各类挑战。
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
431 19
|
JSON 前端开发 Serverless
Mock.js 语法结构全解析
Mock.js 的语法规范介绍,从数据模板定义规范和数据占位符定义规范俩部分介绍, 让你更好的使用 Mock.js 来模拟数据并提高开发效率。
|
机器学习/深度学习 缓存 自然语言处理
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
Tiktokenizer 是一款现代分词工具,旨在高效、智能地将文本转换为机器可处理的离散单元(token)。它不仅超越了传统的空格分割和正则表达式匹配方法,还结合了上下文感知能力,适应复杂语言结构。Tiktokenizer 的核心特性包括自适应 token 分割、高效编码能力和出色的可扩展性,使其适用于从聊天机器人到大规模文本分析等多种应用场景。通过模块化设计,Tiktokenizer 确保了代码的可重用性和维护性,并在分词精度、处理效率和灵活性方面表现出色。此外,它支持多语言处理、表情符号识别和领域特定文本处理,能够应对各种复杂的文本输入需求。
1608 6
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
|
数据采集 前端开发 JavaScript
金融数据分析:解析JavaScript渲染的隐藏表格
本文详解了如何使用Python与Selenium结合代理IP技术,从金融网站(如东方财富网)抓取由JavaScript渲染的隐藏表格数据。内容涵盖环境搭建、代理配置、模拟用户行为、数据解析与分析等关键步骤。通过设置Cookie和User-Agent,突破反爬机制;借助Selenium等待页面渲染,精准定位动态数据。同时,提供了常见错误解决方案及延伸练习,帮助读者掌握金融数据采集的核心技能,为投资决策提供支持。注意规避动态加载、代理验证及元素定位等潜在陷阱,确保数据抓取高效稳定。
533 17
|
存储 机器学习/深度学习 应用服务中间件
阿里云服务器架构解析:从X86到高性能计算、异构计算等不同架构性能、适用场景及选择参考
当我们准备选购阿里云服务器时,阿里云提供了X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器以及高性能计算等多种架构,每种架构都有其独特的特点和适用场景。本文将详细解析这些架构的区别,探讨它们的主要特点和适用场景,并为用户提供选择云服务器架构的全面指南。
1301 18
|
人工智能 监控 前端开发
基于 Next.js 的书法字体生成工具架构设计与 SSR 优化实践
本项目是一款书法字体生成工具,采用 Next.js 14(App Router)与 Tailwind CSS 构建前端,阿里云 Serverless 部署后端。通过混合渲染策略(SSG/SSR/CSR)、Web Worker 异步计算及 CDN 字体分片加载优化性能。服务端借助阿里云函数计算处理计算密集型任务,将平均耗时从 1200ms 降至 280ms,支持 1000+ QPS。动态路由与 ARMS 监控提升工程化水平,未来计划引入 WebGPU 和 AI 字体风格迁移技术,进一步优化用户体验。

热门文章

最新文章

推荐镜像

更多
  • DNS