node.js 技术架构

264 阅读4分钟

node.js

node.js不是什么?

不是web框架

  • Node.js并不是web后端框架

  • 不能把Node.jsFlask或者Spring对比

不是编程语言

  • Node.js并不是后端的JS

  • 不能把Node.jsPython或者PHP对比

node.js是什么?

是一个平台

  • 它将多种技术组合起来

  • JavaScript也能调用系统接口、开发后端应用

Node.js用到了哪些技术

  • V8引擎

  • libuv

  • C/C++实现的c-areshttp-parserOpenSSLzlib等库

Node.js技术架构

image.png

深入理解Node.js

Node.js工作流程

image.png

什么是bindings?

Node Bindings 是沟通JSC++的桥梁,封装V8Libuv的细节,向上层提供基础API服务。

背景

  • C/C++实现了一个http_parser库,很高效

  • 只会写JS,但是想调用这个库

  • 直接调用肯定不能成功的,需要一个中间的桥梁,这个桥梁就是bindings

bindings

  • Node.jsC++http_parser进行封装,使它符合某些要求,封装的问价叫做http_parser_bindings.cpp

  • Node.js提供的编译工具将其编译为.node文件

  • JS代码可以直接require这个.node文件

  • 这样JS就能调用C++库,中间的桥梁就是binding

  • 由于Node.js提供了很多binding,所以加个s,这就是bindings

JS与C++交互

JS调用C++代码

C++调用JS回调

libuv是什么?

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

背景

  • node.js最初开始于2009年,是一个可以让Javascript代码离开浏览器的执行环境也可以执行的项目。 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。libuv提供了一个跨平台的抽象,由平台决定使用libev或IOCP。在node-v0.9.0版本中,libuv移除了libev的内容。

功能

  • 可以用于TCP/UDP/DNS/文件等的异步操作

TCP:传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 说白了TCP就是一种传输协议,就像HTTP协议一样,HTTP的目的是指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应,而TCP的目的是为了确保数据传输的可靠性,我给你一个数据包,你一定就要收到,收不到的话那么我就会给你重发,直到我超时放弃你了。 HTTP是建立在TCP之上的,当你建立起TCP连接之后,在上面传输的数据用的是HTTP协议。

UDP

image.png

DNS

image.png

V8是什么?

功能

  • 将JS源代码变成本地代码并执行

  • 维护调用栈,确保JS函数的执行顺序

  • 内存管理,为所有对象分配内存

  • 垃圾回收,重复利用无用的内存

  • 实现JS的标准库

注意:

  • V8不提供DOM API

  • V8执行JS是单线程的

  • 可以开启两个线程分别执行JS

  • V8本身是包含多线程的,如垃圾回收为单独线程

  • 自带event loop ,但Node.js基于libuv自己做了一个

Event Loop是什么?

什么是Event

一般情况下,event分两种,一种是内部的,一种是外部的

  • 计时器到期了(内部)

  • 文件可以读取了、读取出错了(外部)

  • socket有内容了、关闭了(外部)

什么是Loop

  • loop就是循环,比如while(true)循环

  • 由于事件是分优先级的,所以处理起来也是分先后的

  • 所以Node.js需要按顺序轮询每种事件

  • 这种轮询往往都是循环的,1>2>3>1>2>3

Event Loop

  • 操作系统可以触发事件,JS可以处理事件

  • Event Loop就是对事件处理顺序的管理

Event Loop

Event Loop文档

顺序示意图

image.png

  • timers 阶段:这个阶段执行 setTimeout 和 setInterval 的回调函数。

  • I/O callbacks 阶段:不在 timers 阶段、close callbacks 阶段和 check 阶段这三个阶段执行的回调,都由此阶段负责,这几乎包含了所有回调函数。

  • idle, prepare 阶段(译注:看起来是两个阶段,不过这不重要):event loop 内部使用的阶段(译注:我们不用关心这个阶段)

  • poll 阶段:获取新的 I/O 事件。在某些场景下 Node.js 会阻塞在这个阶段。

  • check 阶段:执行 setImmediate() 的回调函数。

  • close callbacks 阶段:执行关闭事件的回调函数,如 socket.on('close', fn) 里的 fn。

一个 Node.js 程序结束时,Node.js 会检查 event loop 是否在等待异步 I/O 操作结束,是否在等待计时器触发,如果没有,就会关掉 event loop。

重点阶段

  • timers检查计时器

  • poll轮询,检查系统事件

  • check检查setImmediate回调

  • 其他阶段用的少

注意:

  • 大部分时间,Node.js都停在poll轮询阶段

  • 大部分事件都在poll阶段被处理,如文件、网络请求

总结

image.png

Node.js API

英文文档

中文文档

image.png