Node理解(从起源、操作系统层面理解)

参考文章:

  1. https://www.cnblogs.com/momoyan/p/9128076.html
  2. https://www.jianshu.com/p/a8f5a8cdc6ab
  3. https://www.ibm.com/developerworks/cn/opensource/os-nodejs/

node简介

1. node起源

最初javascript只能运行在浏览器,靠的是JS引擎把javascript代码转换成浏览器能识别的机器码,并且不同的浏览器用的是不同的引擎。因此,有时候 js 在不同的浏览器中运行会有不同的效果。这些 Javascript 引擎都遵循 ECMAScript 标准,Javascript 则是 ECMAScript 的一个方言版本,能够被web浏览器和许多其它的应用支持。

浏览器是一个能够运行javascript代码的运行环境,在js中,我们能够访问全局变量windowdocument。这些变量能够让我们与代码所运行的环境进行交互。

node的创始人想着如果javascript能够在浏览器以外的地方运行就好了。因此,他就把速度最快的javascript引擎——GoogleV8引擎嵌入到了一个C++程序中,并把这个程序叫做Node

在这里插入图片描述

2. node是什么?
  1. Node 既不是一种语言,也不是一个框架,而是一个能执行 JavaScript 代码的运行时环境。它是一个服务器程序。
  2. 跟浏览器类似,Node也是一个javascript代码的运行时环境。它包含一个JS引擎。能够执行javascript代码。但它和浏览器不同的是,它还提供能够支持其他功能的一些对象。没有了能够获取DOMdocument对象。但是能够进行文件或者网络操作(这些操作需要借助于一些库来实现,如libuv(下面会提到)
  3. Node 是一个服务器端 JavaScript 解释器,用于方便地搭建响应速度快、易于扩展的网络应用。==Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,==非常适合在分布式设备上运行数据密集型的实时应用。
3. Node目录及架构体系

在这里插入图片描述

  1. github中,我们可以看到node库的目录,其中:
    deps:包含了node所依赖的库
    lib:包含了我们在项目中引入的用javascript定义的函数和模块。
    srclib库对应的c++实现。是Node实际导入LibuvV8的地方。也是我们正在使用的所有函数和模块实际实现的地方。

  1. node一些具体的所依赖的库的作用
    v8引擎:将js转成C++
    libuv:用于在c++中处理并发和进程构建,具有跨平台和异步能力。
    c-ares:提供了异步处理DNS相关的能力
    http_parser、OpenSSL、zlib等:提供了解析httpSSL数据压缩等能力。
v8Libuv
v8

谷歌开源的JavaScript引擎。目的是使JavaScript能够在浏览器之外的地方运行起来。Javascript引擎是一个能够将 Javascript 语言转换成浏览器能够识别的低级语言或机器码的程序。

Libuv

C++的开源项目,使 Node 能够访问操作系统的底层文件系统(file system),访问网络(networking)并且处理一些高并发相关的问题。

需要Node干什么?

你可能在想,既然V8能够让我们使用JavaScriptLibuv能够让我们使用一些操作系统、网络等层面的操作,我们需要Node干什么?

原因:

  • 由于V8和libuv都并非是用JavaScript写的,对于前端而言,熟悉的是JS而非C++,而Node为我们提供了接口,用来将JavaScript应用程序的JavaScript端与实际运行在我们计算机的C++关联起来,从而实际地解释和执行JavaScript代码
  • Node封装了一系列的API供我们使用,并且提供了一致的接口。
Node是如何运行的?

在这里插入图片描述

扫描二维码关注公众号,回复: 9008202 查看本文章
  • Process.binding/InternalBinding实际上是C++函数,是用于将Node标准库中C++端和JavaScript端连接起来的桥梁。也是Node帮我们实现大量内部工作的地方。
  • 当运行JavaScript代码时,实际上它做了映射,依赖的实际上为C++代码。
  • V8本质上是作为一个完整的中介,允许在JavaScript中所定义的值转换成等价类型的C++的值。
  • Libuv用于C++端的并发和进程处理。
4. Node解决了什么?

在java和PHP这类语言中,每个链接都会生成一个新线程。每个线程需要分配内存,随着客户群的增长,如果希望web应用程序支持更多用户,那么,必须添加更多服务器。当然,这会增加服务器成本、流量成本和人工成本等成本。除这些成本上升外,还有一个潜在技术问题,即用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。鉴于上述所有原因,整个 Web 应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器能够处理的并发连接的最大数量

Node解决这个问题的方法是:更改连接到服务器的方式。每个连接发射一个在Node引擎的进程中运行的事件。而不是为每个连接生成一个新的OS线程(并为其分配一些配套内存)。Node通过更改连接到服务器的方式,可以处理高并发任务。

5. Node能做什么?

JavaScript为客户端而生,Node.js为网络而生。使用Node.js,可以实现:

  • 具有复杂逻辑的网站;
  • 基于社交网络的大规模 Web 应用;
  • Web Socket 服务器;
  • TCP/UDP 套接字应用程序;
  • 命令行工具;
  • 交互式终端程序;
  • 带有图形用户界面的本地应用程序;
  • 单元测试工具;
  • 客户端 JavaScript 编译器。
6. 什么是事件驱动编程
  1. 事件驱动编程:为需要处理的事件编写相应的事件处理程序。代码在事件发生时执行。
  2. 早期的非事件驱动的程序要等待某个条件触发,需要不断地检查这个条件,直到条件满足。这样是很浪费cpu时间的。而事件驱动的程序,则有机会释放cpu从而进入睡眠状态。当事件触发时被操作系统唤醒,这样就能更有效地使用cpu。
7.Node.js运行原理分析

说在前面(对比体现Node.js的优点):

  • 应用程序的请求过程可以分为两个部分:cpu运算和I/O读写。CPU计算速度通常远高于磁盘读写速度,这就导致CPU运算已经完成,但是不得不等待磁盘I/O任务完成之后再继续接下来的业务。
  • I/O实际上才是应用程序的瓶颈所在。 在I/O密集型业务中,假设请求需要100ms来完成,其中99ms化在I/O上。如果需要优化应用程序,让他能同时处理更多的请求,我们会采用多线程,同时开启100个、1000个线程来提高我们请求处理,当然这也是一种可观的方案。
  • 多线程不足:由于一个CPU核心在一个时刻只能做一个事情,操作系统只能通过将CPU切分为时间片的方法,让线程较为均匀地使用CPU。但操作系统在内核切换线程的同时也要切换线程的上下文,当线程数量过多时,时间将会被消耗在上下文切换中。所以在大并发时,多线程结构还是无法做到强大的伸缩性。
  • 相对比多线程,单线程的最大好处是不用像多线程编程那样处处在意状态的同步问题,这里没有死锁的存在,也没有线程上下文切换所带来的性能上的开销
  • Node.js的单线程并不是真正的单线程,只是开启了单个线程进行业务处理(CPU的运算),同时开启了其他线程专门处理I/O。当一个指令到达主线程,主线程发现有I/O之后,直接把这个事件传给I/O线程,不会等待I/O结束后再去处理下面的业务。而是拿到一个状态后立即往下走。即单线程、异步I/O
  • I/O操作完后,Node.js的I/O处理完之后会有一个回调事件。这个事件会放在一个事件处理队列中,在进程启动时node会创建一个类似于while(true)的循环,它的每一个轮询都会去查看是否有事件需要处理,是否有事件关联的回调函数需要处理,如果有就处理,然后加入下一个轮询。如果没有就退出进程。这便从Node的角度解释了什么是“事件驱动”
发布了72 篇原创文章 · 获赞 72 · 访问量 6307

猜你喜欢

转载自blog.csdn.net/weixin_43314846/article/details/103190381
今日推荐