关闭

了解node.js事件循环

时间: 2018-06-08阅读: 1238标签: 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 
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/867

在Node.js 12 中使用 ESM

Node.js 12 之后开始支持 ECMAScript Modules(简称ESM),不过并不是默认开启或者自动切换。坦率地说我也卡了一阵子才搞清楚怎么直接使用。简单记一下吧。

Node.js FS模块方法速查

所有文件操作提供同步和异步的两种方式,本笔记只记录异步的API,异步方式其最后一个参数是回调函数。回调函数的第一个参数往往是错误对象,如果没有发生参数,那么第一个参数可能是null或者undefinded。

在 Node.js 中看 JavaScript 的引用

早期学习 Node.js 的时候 (2011-2012),有挺多是从 PHP 转过来的,当时有部分人对于 Node.js 编辑完代码需要重启一下表示麻烦(PHP不需要这个过程),于是社区里的朋友就开始提倡使用 node-supervisor 这个模块来启动项目

Node 引入 ESM 新方案

Node 对 ES6 Module 的支持又有新进展。一个新的 PR 更新了当前 --experimental-modules 的实现方案。type 动态判断模块加载模式:更新后的方案将根据 package.json 文件中指定的 type 值来判断 js 文件是使用 ESM 还是 commonjs

Node启动https服务器

首先你需要生成https证书,可以去付费的网站购买或者找一些免费的网站,可能会是key或者crt或者pem结尾的。不同格式之间可以通过OpenSSL转换

理解 Node.js 中 Stream(流)

Stream(流) 是 Node.js 中处理流式数据的抽象接口。 stream 模块用于构建实现了流接口的对象。Node.js 提供了多种流对象。 例如,对 HTTP 服务器的request请求和 process.stdout(标准输出), 都是流的实例

query和params在前后端中的区别

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

前端赋能业务 - Node实现自动化部署平台

是否有很多人跟我一样有这样的一个烦恼,每天有写不完的需求、改不完的BUG,每天撸着重复、繁琐的业务代码,担心着自己的技术成长

angular为什么依赖nodejs?

angular用nodejs主要是用它的npm工具包,npm里面有很多很方便的工具可以用在前端开发,Angular是一个开源框架的,以 JavaScript 编写的库,一个客户端的JavaScript MVC框架,用于开发动态Web应用程序。

快速理解 nodejs 模块

module.exports 用于暴露一个值,这个值默认是对象,也可以覆盖为原始值。尝试在一个文件中直接 log 出 module 的值,可以得到:你需要通过修改 module 的 exports 属性来输出你需要输出的东西,而 require 用于导入一个模块

点击更多...

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