Nodejs学习
yuiyake 7/31/2022
# 为什么node是单线程但能处理高并发?
- 首先明确单线程的好处
- 无需像多线程那样去关注线程之间的状态同步问题
- 没有线程切换所带来的开销
- 没有死锁存在
- 为什么能高并发?
- 原因之一就是node具有异步I/O特性,每当有I/O请求发生时,node会提供给该请求一个I/O线程。然后node就不管这个I/O的操作 过程了,而是继续执行主线程上的事件,只需要在该请求返回回调时在处理即可。也就是node省去了许多等待请求的时间。
- 还有一个原因就是事物驱动。主线程通过eventLoop事件循环触发的方式来运行程序。
- node怎么知道请求返回了回调,又应该何时去处理这些回调呢?
- node的另一特性:事务驱动,即主线程通过event loop事件循环触发的方式来运行程序
# node生命周期
- node根据任务的种类和优先级分成了七类:Timers,Pending,Idle,Prepare,Poll,Check,Close
- 对应的生命周期是这样的
┌───────────────────────────┐
┌─>│ timers │ ----事件循环在这个阶段会检查存放定时器的数据结构(最小堆),对其中的定时器进行遍历,逐个比较当前时间和过期时间,
│ │ │ 判断该定时器是否过期,如果过期的话,就将该定时器的回调函数取出并执行。
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │ ----该阶段会执行网络、IO 等异常时的回调。一些 *nix 上报的错误,在这个阶段会得到处理。另外,一些应该在上
│ │ │ 轮循环的 poll 阶段执行的 I/O 回调会被推迟到这个阶段执行。
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │ ---检索新的 I/O 事件;执行与 I/O 相关的回调(除了关闭回调、定时器调度的回调和
│ │ │ │ │ 之外几乎所有回调setImmediate());节点会在适当的时候阻塞在这里。
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │ ----该阶段会依次执行 setImmediate() 的回调。
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │ ----执行一些关闭资源的回调,如 socket.on('close', ...)
└───────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21