node.js 概述

197 阅读2分钟

用到的技术

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

Node.js 技术架构

image.png

什么是 bindings

背景

  • C/C++ 实现了一个 http_parser 库,很高效
  • 如果你只会写JS,但是想调用这个库
  • 直接调用肯定是不能成功的,你需要一个中间的桥梁

bindings

  • Node.js 用 C++ 对 http_parser 进行封装,使它符合某些要求,封装的文件叫做 http_parser_bindings.cpp
  • 用 Node.js 提供的编译工具将其编译为 .node 文件*
  • JS 代码可以直接 require 这个 .node 文件
  • 这样 JS 就能调用 C++ 库,中间的桥梁就是 binding
  • 由于 Node.js 提供了很多 binding,所以加个 s
  • 这就是 bindings

libuv 是什么

背景

  • FreeBSD 系统上有 kqueue
  • Linux 系统上有 epoll
  • Windows 系统上有 IOCP
  • Ryan 为了一个跨平台的异步 I/O 库,开始写 libuv
  • libuv 会根据系统自动选择合适的方案

功能

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

V8 是什么

功能

  • 将 JS 源代码变成本地代码并执行
  • 维护调用栈,确保 JS 函数的执行顺序
  • 内存管理,为所有对象分配内存
  • 垃圾回收,重复利用无用的内存
  • 实现 JS 的标准库

注意

  • V8 不提供 DOM API
  • V8 执行 JS 是单线程的
  • 可以开启两个线程分别执行 JS
  • V8 本身是包含多个线程的,如垃圾回收为单独线程
  • 自带 event loop 但 Node.js 基于 libuv 自己做了一个

Event Loop 是什么

什么是 Event

  • 计时器到期了
  • 文件可以读取了、读取出错了
  • socket 有内容了、关闭了

什么是 Loop

  • loop 就是循环,比如 while(true)循环
  • 由于事件是分优先级的,所以处理起来也是分先后的
  • 所以 Node.js 需要按顺序轮询每种事件
  • 这种轮询往往都是循环的,1->2->3->1->2->3

Event Loop

  • 操作系统可以触发事件,JS 可以处理事件
  • Event Loop 就是对事件处理顺序的管理

顺序示意图

image.png

重点阶段

  • timers 检查计时器
  • poll 轮询,检查系统事件
  • check 检查 setImmediate 回调
  • 其他阶段用的较少

注意

  • 大部分时间,Node.js 都停在 poll 轮询阶段
  • 大部分事件都在 poll 阶段被处理,如文件、网络请求

总结 Node.js

用 libuv 进行一步 I/O 操作

用 event loop 管理事件处理顺序

用 C/C++ 库高效处理 DNS/HTTP...

用 bindings 让 JS 能和 C/C++ 沟通

用 V8 运行 JS

用 Node.js 标准库简化 JS 代码

Node.js API

image.png