了解node.js事件循环

更新日期: 2018-06-08 阅读: 4.1k 标签: node

node.js的第一个基本论点是I / O的性能消耗是很昂贵:



因此,使用当前编程技术的最大浪费来自于等待I / O完成。有几种方法可以处理性能影响(来自Sam Rushing)):

  • 同步:您一次处理一个请求,每个请求依次处理。优点:简单。缺点:任何一个请求都需要等待上一个请求的完成后才执行。

  • 启动一个新的进程:你使用一个新的进程来处理每个请求。优点:容易。缺点:不能很好地扩展,数百个连接意味着数百个进程。 fork()是Unix程序员的锤子。因为它是可用的,所以每个问题看起来都像一个钉子。这通常是矫枉过正

  • 线程:启动一个新线程来处理每个请求。优点:简单,并且比使用fork更亲切,因为线程通常具有更少的开销。 缺点:您的机器可能没有线程,并且线程化编程可能会变得非常复杂,并且担心控制对共享资源的访问。

第二个基础论点是线程每连接的内存很贵:[例如该图表显示了与Nginx相比,Apache吸收内存的每个人都清楚]

Apache是​​多线程的:它为每个请求产生一个线程(或进程,它依赖于conf)。随着并发连接数量的增加以及需要更多线程来为多个同时的客户端服务,您可以看到这种开销如何消耗内存。 Nginx和Node.js不是多线程的,因为线程和进程会带来沉重的内存成本。它们是单线程的,但是基于事件。这消除了数千个线程/进程通过处理单个线程中的多个连接而产生的开销。


Node.js为您的代码保留单个线程...

它确实是一个单线程运行:你不能执行任何并行代码;例如做一个“sleep”会阻塞服务器一秒钟:js while(new Date().getTime()< now + 1000){// do nothing}所以当这段代码运行时,node.js不会响应来自客户端的任何其他请求,因为它只有一个执行代码的线程。或者如果你有一些CPU密集的代码,比如说调整图像大小,那么它仍然会阻止所有其他的请求。


..然而,除了你的代码,所有东西都是并行运行

在单个请求中没有办法让代码并行运行。但是,所有的I / O都是偶数并且是异步的,所以下面不会阻塞服务器:[codesyntax lang =“javascript”]

 c.query(
   'SELECT SLEEP(20);',
   function (err, results, fields) {
     if (err) {
       throw err;
     }
     res.writeHead(200, {'Content-Type': 'text/html'});
     res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');
     c.end();
    }
);

如果你在一个请求中这样做,其他请求可以在数据库运行时进行处理。


为什么要这样处理?我们什么时候从同步到异步/并行执行?

同步执行很好,因为它简化了编写代码(与线程相比,并发问题有导致WTF的倾向)。

在node.js中,你不应该担心后端会发生什么情况:只要在做I / O时使用回调;并确保您的代码永远不会中断,并且执行I / O不会阻止其他请求,而不会导致每个请求的线程/进程成本(例如Apache中的内存开销)。

拥有异步I / O是很好的,因为I / O的更高效,我们应该做更好的事情,而不仅仅是等待I / O。


事件循环是“处理和处理外部事件并将其转换为回调调用的实体”。因此,I / O调用是Node.js可以从一个请求切换到另一个请求的点。在I / O调用中,您的代码会保存回调并将控制权返回给node.js运行时环境。当数据实际可用时,稍后调用回调。

当然,在后端,有数据库访问和流程执行的线程和进程。然而,这些并没有明确暴露给你的代码,所以除了知道I / O交互例如与数据库或与其他进程的异步从每个请求的角度来看,因为这些线程的结果通过事件循环返回到您的代码。与Apache模型相比,线程和线程开销较少,因为每个连接都不需要线程;当你绝对肯定必须有别的东西并行运行时,即使这样管理也是由Node.js来处理的。

除I / O调用外,Node.js预计所有请求都会很快返回;例如应将CPU密集型工作分解到另一个可与事件交互的进程,或使用WebWorkers之类的抽象。这(显然)意味着如果没有另一个线程与您通过事件交互的背景进行交互,则无法并行化代码。基本上,所有发出事件的对象(例如,EventEmitter的实例)都支持异步的偶数交互,并且你可以用这种方式与阻止代码进行交互,例如,使用所有这些都是Node.js中的EventEmitter的文件,套接字或子进程。多核可以使用这种方法完成;另请参阅:node-http-proxy。

内部实施

在内部,node.js依靠libev来提供事件循环,这是libeio的补充,它使用池化线程来提供异步I / O。要了解更多信息,请查看libev文档


那么我们如何在Node.js中进行异步?

Tim Caswell在他精彩的演讲中描述了这些模式:

  • 一流的功能。例如。我们将函数作为数据传递,随机播放并在需要时执行它们。
  • 功能组成。也称为具有匿名函数或闭包,在事件发生在偶数I / O之后执行。
原文链接: blog.mixu.net 
翻译来源:www.zcfy.cc 

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/867

相关推荐

怎么卸载nodejs?

Node.js是一个Javascript运行环境,可以使Javascript这类脚本语言编写出来的代码运行速度获得极大提升,那么安装后该如何卸载呢?下面本篇文章就来给大家介绍一下Windows平台下卸载node.js的方法,希望对大家有所帮助。

happypack提升项目构建速度

运行在 Node.js 之上的 Webpack 是单线程模型的,也就是说 Webpack 需要处理的任务需要一件件挨着做,不能多个事情一起做。happypack把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。

nodejs 异步转同步

nodej项目在微信环境开发,nodejs的异步特效,会导致请求没有完成就执行下面的代码,出现错误。经过多方查找,可以使用async模块来异步转同步,只有前一个function执行callback,下一个才会执行。

node.js反向代理的实现

在实际工程开发中,会有前后端分离的需求。使用node.js反向代理的目的:实现前后端分离,前端减少路径请求的所需的路由文件;通过http-proxy-middleware中间件、Http Proxy 模块这2种方式实现node.js的反向代理

Ubuntu 上 Node.js 安装和卸载

Ubuntu 安装 Node.Js:执行检查可更新的软件,先用普通的apt工具安装低版本的node,然后再升级最新。更换淘宝的镜像,这个是必须的,用过的node的人都知道。安装更新版本的工具N

nodejs 文本逐行读写功能的实现

利用nodejs实现:逐行读写(从一个文件逐行复制到另外一个文件);逐行读取、处理和写入(读取一行,处理后,写入另一个文件)1.所需要的模块: fs,os,readline。功能的实现:readWriteFileByLine.js,功能的调用:index.js

使用pkg打包Node.js应用的方法步骤

Node.js应用不需要经过编译过程,可以直接把源代码拷贝到部署机上执行,确实比C++、Java这类编译型应用部署方便。然而,Node.js应用执行需要有运行环境,意味着你需要先在部署机器上安装Node.js

query和params在前后端中的区别

最近在学node,试着做一个前后端都有的项目,然后就遇到了query和parmas这俩兄弟,你说他们俩长得也不像吧,可这用法实在是太类似了,专门写篇文章来区分这哥俩,分别会从vue路由和Node接收两个角度讲

用node.js开发一个可交互的命令行应用

在这个教程中,我们会开发一个命令行应用,它可以接收一个 CSV 格式的用户信息文件,教程的内容大纲:“Hello,World”,处理命令行参数,运行时的用户输入,异步网络会话,美化控制台的输出,封装成 shell 命令,JavaScript 之外

Node.js 应用:Koa2 使用 JWT 进行鉴权

在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行保护,那么别人就可以很容易地获取并调用这些 API 进行操作。那么服务器端要如何进行鉴权呢?

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!