Node.js 工作机制
V8、libuv、事件循环三者怎么配合跑完一次异步调用。
Key PointsV8 执行 JS,libuv 负责 I/O 与事件循环,回调最终回到主线程排队执行。
三层结构
| Layer | Job |
|---|---|
| Node 标准库(JS) | fs、http、net 等,对下层做封装 |
| V8 | 把 JS 编译成机器码并执行 |
| libuv | 事件循环、线程池、跨平台异步 I/O |
一次 readFile 的全过程
- JS 调用
fs.readFile,进入 C++ 绑定层 - libuv 把任务丢进线程池(默认 4 个线程)
- 主线程立刻返回,继续执行后面的 JS
- 线程池读完文件,把结果放进完成队列
- 事件循环在 poll 阶段取出回调,交给 V8 执行
JavaScript
const fs = require('node:fs');
console.log('1 开始');
fs.readFile(__filename, () => {
console.log('3 回调');
});
setTimeout(() => console.log('2 定时器'), 0);
console.log('4 同步结束');Output
1 开始
4 同步结束
2 定时器
3 回调The order shows three things: sync code runs first; setTimeout callbacks fire in the timers phase; file I/O callbacks wait for the thread pool and usually land after timers.
线程池大小
Bash
# 默认 4,可调
UV_THREADPOOL_SIZE=8 node app.jsThe pool serves **filesystem, dns.lookup, crypto pbkdf2/scrypt and zlib** work. Network sockets do not use the pool — they use epoll/kqueue notifications, so HTTP servers are not limited by those 4 threads.
crypto.pbkdf2 is common in login endpoints. With 4 threads, 8 concurrent logins leave 4 queued on hashing — visible as "slow login at peak". Raise UV_THREADPOOL_SIZE or switch to async WebCrypto.三层结构
| 层 | 职责 |
|---|---|
| Node 标准库(JS) | fs、http、net 等,对下层做封装 |
| V8 | 把 JS 编译成机器码并执行 |
| libuv | 事件循环、线程池、跨平台异步 I/O |
一次 readFile 的全过程
- JS 调用
fs.readFile,进入 C++ 绑定层 - libuv 把任务丢进线程池(默认 4 个线程)
- 主线程立刻返回,继续执行后面的 JS
- 线程池读完文件,把结果放进完成队列
- 事件循环在 poll 阶段取出回调,交给 V8 执行
JavaScript
const fs = require('node:fs');
console.log('1 开始');
fs.readFile(__filename, () => {
console.log('3 回调');
});
setTimeout(() => console.log('2 定时器'), 0);
console.log('4 同步结束');Output
1 开始
4 同步结束
2 定时器
3 回调顺序说明了三件事:同步代码先跑完;setTimeout 的回调在 timers 阶段;文件 I/O 的回调要等线程池返回,通常排在 timers 之后。
线程池大小
Bash
# 默认 4,可调
UV_THREADPOOL_SIZE=8 node app.js池子里排的是**文件系统、DNS 查询(dns.lookup)、crypto 的 pbkdf2/scrypt、zlib 压缩**这些任务。网络 socket 不走线程池,走的是 epoll/kqueue 的事件通知,所以 HTTP 服务不受这 4 个线程限制。
crypto.pbkdf2 是登录接口的常客。默认 4 线程时,8 个并发登录请求会有 4 个排队等哈希,表现为「高峰期登录变慢」。调大 UV_THREADPOOL_SIZE 或改用异步 WebCrypto 能缓解。