【译】理解node.js的事件轮询

        在ManUel Kiessling的《The Node Beginner Book》 Node入门书(http://www.nodebeginner.org/index-zh-cn.html)中说明了Node.js的事件轮询:

        Node.js可以在不新增额外线程的情况下,依然可以对任务进行并行处理 —— Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点 —— 尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。

        然而,要用非阻塞操作,我们需要使用回调,通过将函数作为参数传递给其他需要花时间做处理的函数...

        并提到Mixu的博文,《理解Node.js的事件轮询》,下面就是这篇文章的译文。

译文来源:http://bbs.xyhtml5.com/thread-29-1-1.html

原文出处:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

关于Node.js的第一个基本概念是I/O操作开销是巨大的:


所以,当前变成技术中最大的浪费来自于等待I/O操作的完成。有几种方法可以解决性能的影响:
  同步方式:按次序一个一个的处理请求。利:简单;弊:任何一个请求都可以阻塞其他所有请求。
  开启新进程:每个请求都开启一个新进程。利:简单;弊:大量的链接意味着大量的进程。
  开启新线程:每个请求都开启一个新线程。利:简单,而且跟进程比,对系统内核更加友好,因为线程比进程轻的多;弊:不是所有的机器都支持线程,而且对于要处理共享资源的情况,多线程编程会很快变得太过于复杂。
  第二个基本概念是每个连接都创建一个新线程是很消耗内存的(例如:你可以对比Nginx回想一下Apache内存耗尽的情景)。
  Apache是多线程的:它为每个请求开启一个新的线程(或者是进程,这取决于你的配置),当并发连接增多时,你可以看看它是怎么一点一点耗尽内存的。Nginx和Node.js不是多线程的,因为线程的消耗太“重”了。它们两个是单线程、基于事件的,这就把处理众多连接所产生的线程/进程消耗给消除了。


  Node.js中你的代码运行在单线程之中

确实只有一个线程:你不能并行执行任何代码,比如:下面的“sleep”将会阻塞sever1秒钟:

while(new Date().getTime() < now + 1000) {
   // do nothing
}

当这段代码运行时,Node.js不会响应客户端任何请求,因为只有一个线程来运行你的代码,另外,如果你执行cpu密集的任务,比如重设图像的大小,它也会阻塞所有请求。


     …然而,除了你的代码,其它的一切都是并行执行的

单线程没法让代码并行执行。但是所有I/O操作都是事件驱动、并行的,所以下面的代码不会阻塞server:

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();
    }
);

如果你在一次请求中执行这些,当数据库sleep时,其他请求也会立即被处理。


    为什么异步比较好?什么时候我们应该从同步转移到异步/并行执行呢?

同步执行也不错,因为它简便了我们敲代码。但在使用异步时,你不必关心后端是怎么处理的。而且,在I/O操作时不会阻止其他请求,同时无需承担每个请求所产生的线程/进程的成本。
  I/O操作时使用异步处理很好,因为I/O操作的成本比单纯执行代码要高的多,我们应该在等待I/O时做其它更有意义的工作。


Event loop是指处理外部事件,并把外部事件转换为回调来进行调用的实体(晦涩难懂!!原文:an entity that handles and processes external events and converts them into callback invocations).所以,I/O调用的同时,server就可以去处理另一个请求。在一次I/O调用中,你的代码保存回调函数并把控制权交回到node.js运行时。当数据加载完毕可以访问时,就可以执行回调函数了。
  当然,在后端有很多数据库接入和处理的进程。但是,这些都不需要通过你的代码直接实现,你也就不必了解后台I/O之间的相互作用关系。和Apache相比,省去了很多线程消耗,因为不是每个链接都需要新线程,仅那些需要并行运行的才需要新线程。
  不只是I/O调用,Node.js期望所有的请求都能快速的响应,比如CPU密集的工作应该分离到其他进程,你可以使用事件和他交互。
  内部实现
  在内部,Node.js依赖libev来提供event loop,使用线程池来提供异步I/O。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Node.js中使用WebSocket可以实现实时的双向通信。在Node.js中,可以使用原生的WebSocket模块或者使用第三方库socket.io来实现WebSocket功能。引用\[2\]中给出了使用原生WebSocket模块的示例代码,其中通过创建WebSocket服务器并监听连接事件,可以实现与客户端的通信。引用\[1\]中给出了使用socket.io库的示例代码,通过创建socket.io服务器和客户端,可以实现实时的双向通信。socket.io是在WebSocket之上进行了进一步的封装,提供了更多的功能和兼容性。它可以在WebSocket不可用的情况下自动降级为其他传输方式,如轮询。因此,socket.io更加灵活和可靠。引用\[3\]提到了socket.io是进化了的WebSocket API。总之,Node.js中可以使用原生的WebSocket模块或者socket.io库来实现WebSocket功能,具体选择取决于需求和使用场景。 #### 引用[.reference_title] - *1* [nodejs--websocket](https://blog.csdn.net/qq_36344077/article/details/117338445)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [Node.js实现WebSocket](https://blog.csdn.net/m0_37911706/article/details/128057137)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v4^insert_chatgpt"}} ] [.reference_item] - *3* [借助Nodejs探究WebSocket](https://blog.csdn.net/weixin_30384031/article/details/97687728)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值