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++ 实现:

    1. V8 :提供JavaScript运行环境,提供桥梁接口,可以调用C++
    2. Libuv : 为Node.js开发的一个封装库,提供跨平台的异步I/O能力
    3. 第三方模块:http_parser、OpenSSL、zlib 、C-ares等。提供包括 http 解析、SSL、数据压缩等其他的能力。

image.png

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内部存在线程池,会把任务分配给不同的线程,并把执行结果通知线程池的回调函数,回调函数会被放入事件队列,定时任务轮询事件队列,读取之后执行回调函数。

image.png

node的事件循环

6个阶段处理宏任务:

  • timer阶段:执行setTimeout和setInterval的回调
  • I/O callback: 处理网络、流、TCP的错误回调
  • idle、prepare:闲置阶段,node内部使用
  • poll:执行poll中的I/O队列,检查定时器是否倒是
  • check:存放setImmediate回调
  • close callbacks:关闭回调,例如Socket.on(‘close’)

细节:

  • setTimeout比setImmediate执行更早
  • process.nextTick比Promise.then执行更早
  • 新版的node.js已和浏览器趋同,即兼容代码在两者运行的结果是一样的;

    2、事件驱动

    主体发布消息,其他实例接受消息

    3、单线程

    4、跨平台