理解node.js
1.nodejs诞生
Node之父的Ryan Dahl阻塞式IO是谬误的形式,V8的公布为Node的诞生奠定了松软的根底。
JavaScript自身就是单线程的,而且浏览器发动的AJAX申请就是非阻塞的。所以将JavaScript和异步IO以及一个简略的HTTP服务器汇合在一起,就达到一个比拟好的配合。
尽管Node的非阻塞模型没有了多线程,但却多出了“回调天堂”问题。Ryan认为Node并不适宜用来开发大规模的服务端利用。
相比之下,Go语言(在运行时和操作系统之间所有的IO操作都是非阻塞的,然而它提供给用户的接口却是阻塞式的。)会是更好的抉择。
参考文章:https://www.techug.com/post/n...
2.nodejs简介
个别称 Node.js 是一个平台,它将多种技术组合起来,让 JavaScript 能够调用一些 C/C++ 的接口,拓展了js语言的性能,让 JavaScript 也能调用零碎接口、或进行后端开发的利用。
node.js工作流程:
3.node.js 根本架构
node.js次要分为四大局部:Node Standard Library、Node Bindings、V8、Libuv,架构图如下:
Node Standard Library 是 Node 专门提供给开发人员应用的规范库,如 Http, Buffer, fs 等模块。
Node Bindings 是沟通 JS 和 C++ 的桥梁,封装 V8 引擎 和 Libuv 的细节,向下层提供根底 API 服务。
第三层是撑持 Node.js 运行的要害,由 C/C++ 实现。
V8 是 Google 开发的 JavaScript 引擎,提供 JavaScript 运行环境,能够说它就是 Node.js 的发动机。
Libuv 是专门为 Node.js 开发的一个封装库,提供跨平台的异步 I/O 能力.C-ares:提供了异步解决 DNS 相干的能力。http_parser、OpenSSL、zlib 等:提供包含 http 解析、SSL、数据压缩等其余的能力。
4.Bindings是个啥?
Node Bindings 是沟通 JS 和 C++ 的桥梁,封装 V8 引擎 和 Libuv 的细节,向下层提供根底 API 服务。
举个例子:C/C++ 实现了一个 http_parser 的库,十分高效,然而前端开发人员只会写 JavaScript,间接调用这个库必定是不能胜利的,所以就须要一个两头的桥梁。于是 Node.js 的作者就用 C++ 对 http_parser 库进行封装,使它合乎某些要求(比方对立数据类型等),封装的文件叫做 http_parser_bindings.cpp。同时 Node.js 提供的编译工具能够将其编译为.node文件。这样 JavaScript 代码能够间接 require 这个 .node 文件,这样 JavaScript 就能调用 C++ 库。
5.为什么是 libuv?
Node.js 最早时是应用了 Google 的 V8 解析引擎 和 Marc Lehmann 的 libev。Node.js 将事件驱动的 I/O 模型与适宜该模型的编程语言(JavaScript)交融在了一起,但随着 Node.js 的日益风行,Node.js 也须要同时反对 Windows,然而 libev 只能在 Unix 环境下运行,而在 Windows 零碎平台上与 kqueue(FreeBSD) 或者 (e)poll(Linux) 等内核事件告诉相应的机制是 IOCP。
基于上述背景,Node.js 之父 Ryan 就着手开发了一个 跨平台的异步 I/O 库,将上述操作系统对应的库都整合到一起,于是乎就诞生了 libuv,libuv 会依据不同的操作系统主动抉择适合的计划,它的所有性能都是异步的,个别是用于 操作TCP/UDP/DNS/文件等的异步操作。
为啥是异步?因为即使是 SSD 的拜访相较于高速的 CPU,依然是慢速设施。于是基于 事件驱动 的 IO 模型就应运而生,解决了高速设施同步期待慢速设施或拜访的问题。这不是 libuv 的独创,linux kernel 原生反对的 NIO也是这个思路。 但 libuv 对立了网络拜访,文件拜访,做到了跨平台。
上述 libuv 的架构图中,从左往右分为两局部,一部分是与网络I/O相干的申请,而另外一部分是由文件I/O, DNS Ops以及User code组成的申请。
从图中能够看出,对于Network I/O和以File I/O为代表的另一类申请,异步解决的底层撑持机制是齐全不一样的。
对于Network I/O 相干的申请, 依据 OS 平台不同,别离应用 Linux 上的 epoll,OSX 和 BSD 类 OS 上 的 kqueue,SunOS 上的event ports 以及 Windows 上的 IOCP 机制。而对于 File I/O 为代表的申请,则应用 thread pool。利用 thread pool 的形式实现异步申请解决,在各类 OS 上都能取得很好的反对。
5.V8引擎是啥?
V8 是目前商用的执行 JavaScript 最快的一个引擎(可间接将js代码编译成二进制文件)
,它的性能有很多:将 JavaScript 源代码变成本地代码并执行、保护 JavaScript 的调用栈,确保 JavaScript 函数的执行程序、负责内存治理,为所有对象分配内存、垃圾回收,反复利用无用的内存、实现JS的规范库。
当初 JS 引擎的执行过程大抵是:源代码 --->形象语法树 --->字节码 --->JIT--->本地代码。
V8 更加间接的将形象语法树通过 JIT 技术转换老本地代码,放弃了在字节码阶段能够进行的一些性能优化,但保障了执行速度。 在 V8 生成本地代码后,也会通过 Profiler 采集一些信息,来优化本地代码。尽管,少了生成字节码这一阶段的性能优化, 但极大缩小了转换工夫。
这里有几个留神的点:V8 是不提供 DOM API 的,那是浏览器所提供的、V8 自身是蕴含多个线程的,但它执行 JS 的过程是单线程的、V8 本人自带了 Eventloop,然而 Node.js 基于 libuv 本人做了一个。理解更多v8引擎原理可参考:https://zhuanlan.zhihu.com/p/...
本人简化:
原文链接:https://blog.csdn.net/Marker_...