美文网首页
Node.js简介

Node.js简介

作者: VV木公子 | 来源:发表于2019-07-30 02:30 被阅读0次

    你今天绕过的所有问题,最终会在将来的某一天与你迎头相撞。

    简介

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
    Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
    Node.js不是一种独立的语言。Node.js用JavaScript进行编程, 运行平台是包装后的js引擎(V8)。和PHP, JSP等语言不同,他们都需要运行在服务器上,例如apache,tomat,nginx,IIS,Node.js不用架设在任何服务器软件之上。

    Node.js运行原理

    应用程序的请求过程通常可以分为两部分:CPU运算和I/O读写,CPU计算速度通常远高于磁盘读写速度,所以如果一个CPU需要操作磁盘数据的时候,很有可能不得不等待漫长而耗时的磁盘I/O操作完成。所以,如果同步的等待磁盘I/O操作对CPU资源将是极大的浪费。所以Node.js提出了非阻塞异步I/O的想法。
    对于I/O密集型业务而非计算密集型业务而言,I/O才是应用程序的瓶颈。假设一个异步请求或者一个异步任务需要100ms来完成,其中99ms浪费在磁盘I/O上。如果需要优化应用程序,让他能同时处理更多的请求,我们会采用多线程(比如Java语言中通常这样处理),让CPU同时开启成百上千个线程来提高我们请求处理,当然这也是一种可观的方案。
    但是由于一个CPU核心在一个时刻只能做一件事情,操作系统只能通过将CPU切分为时间片,让线程可以较为均匀的使用CPU资源从而达到一种伪多线程。但操作系统在内核切换线程的同时也要切换线程的上线文,当线程数量过多时,线程上下文的切换将是非常消耗时间的。所以在大并发的异步任务中,多线程结构还是无法做到强大的伸缩性。并且多线程的另一个危险之处在于将线程的管理切换暴露给了上层的开发者,这样的风险就是极有可能因为线程管理不当导致线程灾难性的风险,比如死锁导致程序卡死、线程过多导致性能急剧下降。
    那么是否可以另辟蹊径呢?答案就是单线程,《深入浅出Node》一书提到 “单线程的最大好处是不用像多线程编程那样处处在意状态的同步问题,这里没有死锁的存在,也没有线程上下文切换所带来的性能上的开销”,那么一个线程一次只能处理一个请求岂不是无稽之谈,先让我们看张图:

    the node.js system

    Node.js的单线程并不是真正的单线程,只是开启了单个线程进行业务处理(cpu的运算),同时开启了其他线程作为辅助线程专门处理I/O。也就是说Node.js中存在一个CPU运算的主线程,同时还存在专门处理I/O操作的辅助线程。当一个指令到达主线程,主线程发现有I/O之后,直接把这个事件传给I/O线程,不会同步的等待I/O结束再去处理后面的业务,而是拿到一个状态后立即往下走,这就是“单线程”、“异步I/O”。
    I/O操作完之后呢?Node.js的I/O 处理完之后会有一个回调事件,这个事件会放在一个事件处理队列里(之所以是队列自不必说),在进程启动时node会创建一个类似于While(true)的循环,它的每一次轮询都会去执行栈查看是否有事件需要处理,是否有事件关联的回调函数需要处理。如果有就处理,然后进入下一个轮询。如果没有就退出进程,这就是所谓的事件驱动。这也从Node的角度解释了什么是”事件驱动”。
    在node.js中,事件主要来源于网络请求,文件I/O等,根据事件的不同对观察者进行了分类,有文件I/O观察者,网络I/O观察者。事件驱动是一个典型的生产者/消费者模型,请求到达观察者那里,事件循环从观察者进行消费,主线程就可以马不停蹄的只关注业务不用再去进行I/O等待。
    Node.js运行原理总结:
    1)所有同步任务都在主线程上执行,形成一个执行栈
    2)主线程之外,还存在一个任务队列;只要异步任务有了运行结果,就在任务队列之中放置一个事件
    3)一旦执行栈中的所有同步任务执行完毕(栈空),系统就会读取任务队列,将队列中的事件放到执行栈中依次执行
    4)主线程从任务队列中读取事件(通常是异步I/O的callback)进行处理,如此循环往复

    特点

    通过以上原理,不难看出,Node.js主要包括以下几个特点:
    1.单线程
    2.非阻塞异步I/O
    3.事件驱动

    正是因为Node.js是所谓的“单线程” + “异步I/O” + “事件驱动”,所以Node.js仅适用于I/O密集型的业务而非CPU密集型业务。所谓CPU密集型即指计算密集型,即存在大量需要CPU计算的任务,比如for循环100000次打印log。如果存在CPU密集型将会阻塞Node.js主线程,导致整个程序被卡住直到for循环结束。
    不适用于CPU密集型任务大改也算是Node.js的缺点。这种缺点正是其天生不可避免的。

    因为Node.js当中所有的I/O都是异步的任务, 都是回调函数嵌套回调函数。所以Node.js中通常会出现很多callback。
    Node.js 的包管理器 npm(node package manager),是全球最大的开源库生态系统

    相关文章

      网友评论

          本文标题:Node.js简介

          本文链接:https://www.haomeiwen.com/subject/admwrctx.html