node.js 概述
用到的技术
- V8 引擎
- libuv
- C/C++ 实现的 c-ares、http-parser、OpenSSL、zlib等库
Node.js 技术架构

什么是 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 就是对事件处理顺序的管理
顺序示意图

重点阶段
- 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
