Node.js(一): 技术架构

131 阅读3分钟

Node.js不是什么

  1. 不是web框架:不能把Node.js与Flask或Spring相对比
  2. 不是编程语言:Node.js并不是后端的JS,所以不能与Python或PHP对比

Node.js是什么

  • 是一个平台:它将多种技术组合起来,让JavaScript也能调用系统接口、开发后端应用

Node.js用到了哪些技术

  • V8引擎
  • libuv
  • C/C++实现的高性能库:如c-ares、http-parser、OpenSSL、zlib等

Node.js技术架构

3ba7a509d02ac429af59320f562f64c.png 修正:steam模块 => stream模块

推荐一个源码分析教程:深入理解Node.js:核心思想与源码分析 (github.com)

什么是bindings

C/C++实现了一个高性能的http_parser库,作为JS开发者想要调用这个库,直接调用是是不能成功的,所以需要一个中间层实现JS与C/C++的通信。
Node.js用C++对http_parser进行封装,使它符合某些要求,封装的文件叫做'http_server_bindings.cpp'。再用Node.js提供的编译工具将其编译为'.node'文件(或其他可行的格式文件),从而JS代码可以直接require这个'.node'文件,实现了JS调用C++库,这个中间层就是binding。
由于Node.js提供了很多binding,所以使用复数形式。

libuv是什么

这是一个跨平台的异步I/O库,在libuv之前,不同的OS有不同的I/O库。FreeBSD上有kqueue,Linux上有epoll,Windows系统上有IOCP,但没有跨平台的解决方案。libuv就是为这个而生的,它会根据OS自动选择合适的方案。它可以用于TCP/UDP/DNS/文件等的异步操作。

V8是什么

功能:

  • 将JS源代码变成本地代码并执行
  • 维护调用栈,确保JS函数的执行顺序
  • 内存管理,为所有对象分配内存
  • 垃圾回收,本质目的是重复利用无用的内存
  • 实现JS的标准库 需要注意的是:
  • V8不提供DOM API(这个是浏览器提供的)
  • V8本身虽然是多线程的,但V8执行JS是单线程的,可以开启两个线程分别执行JS
  • V8的多线程体现在:执行JS是一个线程,垃圾回收、内存管理等都是不同的线程
  • 自带event loop,但Node.js基于libuv自己做了一个

Event Loop是什么

在讲Event Loop之前,需要把这个概念分开来解释一下。
什么是Event?Event就是各种事件,可以是内部事件如设置的计时器到期了,外部事件如文件可以读取了、读取出错了,再比如socket有内容了、关闭了。
什么是Loop?直译就是循环。由于事件是分优先级的,所以事件处理也分先后。
所以Node.js需要按顺序轮询每种事件,这种轮询往往都是循环的。Event Loop就是对事件处理顺序的管理。
Event Loop顺序示意图

1656992254061.png

重点阶段在于:

  • timers检查计时器
  • poll轮询,检查系统事件
  • check检查setImmediate回调 其他的阶段则用的较少。
    大部分时间里Node.js都停留在poll阶段,且大部分事件都在poll阶段被处理,如文件、网络请求等。

总结

Node.js是一个结合多种技术,脱离浏览器,用JavaScript开发应用的平台。

  • 用libuv进行异步I/O操作
  • 用event loop管理事件处理顺序
  • 用C/C++库高效处理DNS/HTTP/CTP...
  • 用bindings实现JS和C/C++的通信,还可以自己开发C++插件,增强JavaScript的潜能
  • 用V8引擎运行JS
  • 用Node.js标准库简化JS代码

展示下Node.js工作流程图,从图中可以看出,我们的JS代码其实只占到很小一部分。 image.png

Node.js学习资源

  1. 官方文档
  2. Node.js 16 LTS documentation — DevDocs