Node.js不是什么
- 不是web框架:不能把Node.js与Flask或Spring相对比
- 不是编程语言:Node.js并不是后端的JS,所以不能与Python或PHP对比
Node.js是什么
- 是一个平台:它将多种技术组合起来,让JavaScript也能调用系统接口、开发后端应用
Node.js用到了哪些技术
- V8引擎
- libuv
- C/C++实现的高性能库:如c-ares、http-parser、OpenSSL、zlib等
Node.js技术架构
修正:steam模块 => stream模块
推荐一个源码分析教程:深入理解Node.js:核心思想与源码分析 (github.com)
什么是bindings
C/C++实现了一个高性能的http_parser库,作为JS开发者想要调用这个库,直接调用是是不能成功的,所以需要一个中间层实现JS与C/C++的通信。
Node.js用C++对http_parser进行封装,使它符合某些要求,封装的文件叫做'http_server_bindings.cpp'。再用Node.js提供的编译工具将其编译为'.node'文件(或其他可行的格式文件),从而JS代码可以直接require这个'.node'文件,实现了JS调用C++库,这个中间层就是binding。
由于Node.js提供了很多binding,所以使用复数形式。
libuv是什么
这是一个跨平台的异步I/O库,在libuv之前,不同的OS有不同的I/O库。FreeBSD上有kqueue,Linux上有epoll,Windows系统上有IOCP,但没有跨平台的解决方案。libuv就是为这个而生的,它会根据OS自动选择合适的方案。它可以用于TCP/UDP/DNS/文件等的异步操作。
V8是什么
功能:
- 将JS源代码变成本地代码并执行
- 维护调用栈,确保JS函数的执行顺序
- 内存管理,为所有对象分配内存
- 垃圾回收,本质目的是重复利用无用的内存
- 实现JS的标准库 需要注意的是:
- V8不提供DOM API(这个是浏览器提供的)
- V8本身虽然是多线程的,但V8执行JS是单线程的,可以开启两个线程分别执行JS
- V8的多线程体现在:执行JS是一个线程,垃圾回收、内存管理等都是不同的线程
- 自带event loop,但Node.js基于libuv自己做了一个
Event Loop是什么
在讲Event Loop之前,需要把这个概念分开来解释一下。
什么是Event?Event就是各种事件,可以是内部事件如设置的计时器到期了,外部事件如文件可以读取了、读取出错了,再比如socket有内容了、关闭了。
什么是Loop?直译就是循环。由于事件是分优先级的,所以事件处理也分先后。
所以Node.js需要按顺序轮询每种事件,这种轮询往往都是循环的。Event Loop就是对事件处理顺序的管理。
Event Loop顺序示意图
重点阶段在于:
- timers检查计时器
- poll轮询,检查系统事件
- check检查setImmediate回调
其他的阶段则用的较少。
大部分时间里Node.js都停留在poll阶段,且大部分事件都在poll阶段被处理,如文件、网络请求等。
总结
Node.js是一个结合多种技术,脱离浏览器,用JavaScript开发应用的平台。
- 用libuv进行异步I/O操作
- 用event loop管理事件处理顺序
- 用C/C++库高效处理DNS/HTTP/CTP...
- 用bindings实现JS和C/C++的通信,还可以自己开发C++插件,增强JavaScript的潜能
- 用V8引擎运行JS
- 用Node.js标准库简化JS代码
展示下Node.js工作流程图,从图中可以看出,我们的JS代码其实只占到很小一部分。