Nodejs的运行原理-架构篇

前言node

原本是想只作一个Nodejs运行原理-科普篇,可是收到了很多私信,要我多分享一些更进阶,更详细的内容,因此我会在接下来的两个月里继续更新Nodejs运行原理。api

PS:此系列只作Nodejs的运行原理(架构,libuv,v8 etc),并不介绍Nodejs功能以及使用方法。多线程

本文以两个view来看Nodejs的架构,一个是从模块依赖的角度,另外一个是从函数调用的角度。架构

1.模块依赖异步

如上图所示:your code 为编辑代码,node.js 核心,Host environment 为宿主环境(提供各类服务,如文件管理,多线程,多进程,IO etc)socket

1.1node.jstcp

这里重点介绍,nodejs组成部分:v8 engine, libuv, builtin modules, native modules以及其余辅助服务。函数

v8 engine:主要有两个做用 1.虚拟机的功能,执行js代码(本身的代码,第三方的代码和native modules的代码)。ui

               2.提供C++函数接口,为nodejs提供v8初始化,建立context,scope等。spa

libuv:它是基于事件驱动的异步IO模型库,咱们的js代码发出请求,最终由libuv完成,而咱们所设置的回调函数则是在libuv触发。

builtin modules:它是由C++代码写成各种模块,包含了crypto,zlib, file stream etc 基础功能。(v8提供了函数接口,libuv提供异步IO模型库,以及一些nodejs函数,为builtin modules提供服务)。

native modules:它是由js写成,提供咱们应用程序调用的库,同时这些模块又依赖builtin modules来获取相应的服务支持

简单总结一下:若是把nodejs看作一个黑匣子,起暴露给开发者的接口则是native modules,当咱们发起请求时,请求自上而下,穿越native modules,经过builtin modules将请求传送至v8,libuv和其余辅助服务,请求结束,则从下回溯至上,最终调用咱们的回调函数。

1.2your code

当咱们执行node xxx.js的时候,node会先作一些v8初试化,libuv启动的工做,而后交由v8来执行native modules以及咱们的js代码。

2.函数调用

这里咱们以创建http server为例

 

如上图所示:v8执行js代码 server.listen()时,会经过一些基础服务到TCPWrap::listen(),TCPWrap是nodejs的內建模块,其经过libuv的api uv_listen()的方式,由libuv来完成异步调用。

图中1,2,3,4,5步骤标明了调用和返回的路径,这几步很快结束,留下callback TCPWrap::OnConnection()等着所须要的数据准备好后被调用。

libuv在获得所须要的请求后,会调用callback TCPWrap::OnConnection(),在该函数最后经过 tcp_wrap->MakeCallback(env->onconnection_string(), ARRAY_SIZE(argv), argv) 调用V8 engine中的JavaScript callback。

Node.js内建模块http实际上是创建在模块net之上的。若是看net.js代码会发现,其经过 new TCP() 返回的类对象完成后续的TCP connect, bind, open等socket动做。

能够看到Node.js作的工做像是一座桥。左手V8,右手libuv,将2者有机链接在一块儿。例如HandleWrap::HandleWrap()中记录了V8 instance中的JavaScript对象以及TCPWrap对象。这样在TCPWrap::OnConnection()中能够拿到这两个对象,执行后续的callback调用。

相关文章
相关标签/搜索