TODO
- 各个模块的解读
[ ]
[x] 来自 egg.js 团队的 Node.js 经验分享:https://www.yuque.com/egg/nodejs
Node 架构
Node的架构主要分为三层:内置核心模块、胶水层、底层。
1、Node Standard Library: 内置核心模块,由Js实现,提供应用程序可直接调用的标准库,如Http, Buffer 模块 。
2、Node Bindings:胶水层,因为JavaScript无法操作底层硬件设置的,所以这一层是找到对于的C++对应暴露的模块,让Nodejs获取到底层的服务支持 ,向上层提供基础API服务 ,需要V8引擎配合实现。
3、底层:第三层是支撑 Node.js 运行的关键,由 C/C++ 实现:- V8 :提供JavaScript运行环境,提供桥梁接口,可以调用C++
- Libuv : 为Node.js开发的一个封装库,提供跨平台的异步I/O能力
- 第三方模块:http_parser、OpenSSL、zlib 、C-ares等。提供包括 http 解析、SSL、数据压缩等其他的能力。
Node.js的运行机制
- V8引擎解析
JavaScript
脚本。 - 解析后的代码,调用Node API。
- libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。
- V8引擎再将结果返回给用户。
Node 的特点
Node诞生的目的就是为了实现高性能的Web服务,高性能的实现主要手段是单线程下的非阻塞IO模型配合事件驱动的方式来实现高并发的。
基于此Nodejs比较适合做IO密集型的操作,比如作为中间层去做一些数据格式化处理,合并接口请求,数据缓存等操作,实时聊天程序等,前端工程化等。不适合做复杂逻辑的处理。
1、非阻塞 IO(异步) 模型
IO是应用的瓶颈所在,异步IO提升性能,无需原地等待结果返回。
IO操作属于操作系统级别的,平台都有对于实现,Node也是一个平台。Nodejs是单线程的,它通过事件驱动架构和底层的Libuv库,重复调用IO操作,判断IO是否结束(Node的事件循环)实现了异步IO。
一般多个请求进来,不会阻塞主线程,而是把任务交给Libuv处理执行,Libuv内部存在线程池,会把任务分配给不同的线程,并把执行结果通知线程池的回调函数,回调函数会被放入事件队列,定时任务轮询事件队列,读取之后执行回调函数。
node的事件循环
6个阶段处理宏任务:
- timer阶段:执行setTimeout和setInterval的回调
- I/O callback: 处理网络、流、TCP的错误回调
- idle、prepare:闲置阶段,node内部使用
- poll:执行poll中的I/O队列,检查定时器是否倒是
- check:存放setImmediate回调
- close callbacks:关闭回调,例如Socket.on(‘close’)
细节: