成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

NodeJS架構(gòu) - 單線程事件循環(huán)模型

leap_frog / 1974人閱讀

摘要:客戶端可能需要等待服務(wù)器釋放可用的線程去處理其請求處理阻塞式的任務(wù)時浪費時間的架構(gòu)單線程事件循環(huán)不遵循請求響應(yīng)多線程無狀態(tài)模型。它采用單線程與事件循環(huán)模型。

這篇譯章探究了NodeJS的架構(gòu)和單線程事件循環(huán)模型。我們將在本文中討論“NodeJS如何在底層工作,它遵循什么類型的處理模型,NodeJS如何使用單線程模型處理并發(fā)請求”等內(nèi)容。

NodeJS 單線程事件循環(huán)模型

正如我們剛才說的,NodeJS使用的是“單線程事件循環(huán)模型”的架構(gòu)去處理多個并發(fā)的客戶端請求的。

有許多Web應(yīng)用程序技術(shù),如JSP,Spring MVC,ASP.NET等。但所有這些技術(shù)都遵循“多線程請求 - 響應(yīng)”架構(gòu)來處理多個并發(fā)客戶端。

我們已經(jīng)熟悉“多線程請求 - 響應(yīng)”架構(gòu),因為它被大多數(shù)Web應(yīng)用程序框架使用。 但是為什么NodeJS選擇了不同的架構(gòu)來開發(fā)Web應(yīng)用程序。多線程和單線程事件循環(huán)體系結(jié)構(gòu)之間的主要區(qū)別是什么?

NodeJS

NodeJS使用“單線程事件循環(huán)模型”架構(gòu)來處理多個并發(fā)客戶端。然而它是如何真正處理并發(fā)客戶端請求且不使用多個線程。什么是事件循環(huán)模型?我們將逐一討論這些概念。

在討論“單線程事件循環(huán)”架構(gòu)之前,首先我們將介紹著名的“多線程請求 - 響應(yīng)”架構(gòu)。

傳統(tǒng)的Web應(yīng)用處理模型

任何非NodeJS開發(fā)的Web應(yīng)用程序通常都遵循“多線程請求 - 響應(yīng)”模型。我們可以將此模型稱為請求/響應(yīng)模型。

客戶端向服務(wù)器發(fā)送請求,然后服務(wù)器根據(jù)客戶端請求進行一些處理,準備響應(yīng)并將其發(fā)送回客戶端。

該模型使用HTTP協(xié)議。由于HTTP是無狀態(tài)協(xié)議,因此該請求/響應(yīng)模型也是無狀態(tài)模型。所以我們可以將其稱為請求/響應(yīng)無狀態(tài)模型。

但是,此模型使用多線程來處理并發(fā)客戶端請求。 在討論這個模型內(nèi)部之前,首先要看下面的內(nèi)容。

請求/響應(yīng)模型處理的步驟:

客戶端發(fā)送一個請求到Web服務(wù)器

Web服務(wù)器內(nèi)部維護一個有限的線程池,以便在客戶端請求提供服務(wù)

Web服務(wù)器處于無限循環(huán)中并等待客戶端傳入請求

Web服務(wù)器處理請求步驟:

接收到一個客戶端請求

從線程池中選擇一個線程

將此線程分配給客戶端請求

此線程讀取客戶端請求,處理客戶端請求,執(zhí)行阻塞的IO操作(如果需要)和準備響應(yīng)

此線程將準備好的請求發(fā)送回Web服務(wù)器

Web服務(wù)器又將此響應(yīng)發(fā)送到相應(yīng)的服務(wù)器

服務(wù)器為所有客戶端執(zhí)行以上步驟,為每一個客戶端請求創(chuàng)建一個線程。

圖表說明:

Client-1, Client-2, ..., Client-n是同時發(fā)送請求到Web服務(wù)器的客戶端應(yīng)用

Web服務(wù)器內(nèi)部維護著一個有限的線程池,線程池中線程數(shù)量為m個

Web服務(wù)器逐個接收這些請求:

Web服務(wù)器拾取Client-1的請求Request-1,從線程池中拾取一個線程T-1并將此請求分配給線程T-1

線程T-1讀取Client-1的請求Request-1, 并處理該請求

該請求無阻塞IO處理

處理完必要的步驟后準備將Response-1發(fā)送回客戶端

Web服務(wù)器又將此Response-1發(fā)送到Client-1

Web服務(wù)器拾取Client-2的請求Request-2,從線程池中拾取一個線程T-2并將此請求分配給線程T-2

線程T-2讀取Client-2的請求Request-2, 并處理該請求

該請求無阻塞IO處理

處理完必要的步驟后準備將Response-2發(fā)送回客戶端

Web服務(wù)器又將此Response-2發(fā)送到Client-2

Web服務(wù)器拾取Client-n的請求Request-n,從線程池中拾取一個線程T-n并將此請求分配給線程T-n

線程T-n讀取Client-n的請求Request-n, 并處理該請求

Request-n需要大量的阻塞IO和計算操作

線程T-n需要更多時間與外部系統(tǒng)(SQL, File System)交互,執(zhí)行必要步驟并準備Response-n并將其發(fā)送回服務(wù)器

Web服務(wù)器又將此Response-n發(fā)送到Client-n

如果"n"大于"m"(大多數(shù)時候,它是真的),則在使用完所有的m個線程之后,剩余的客戶端請求會在隊列中等待。

如果這些線程中有大量的阻塞IO操作(例如:和數(shù)據(jù)庫、文件系統(tǒng)、外部服務(wù)等交互),那么剩余的客戶端也會等待更長的時間。

一旦線程池中的線程空閑且可用于下一個任務(wù),服務(wù)器就會拾取這些線程并將它們分配給剩余的客戶端請求。

每個線程都會使用到許多資源,如內(nèi)存等。因此,在將這些線程從忙狀態(tài)轉(zhuǎn)到等待狀態(tài)之前,它們應(yīng)該釋放所有獲取的資源。

請求/響應(yīng)無狀態(tài)模型的缺點:

在處理越來越多的并發(fā)客戶端請求時會變得棘手

當(dāng)客戶端請求增加時,線程也會越來越多,最后它們會占用更多內(nèi)存。

客戶端可能需要等待服務(wù)器釋放可用的線程去處理其請求

處理阻塞式的IO任務(wù)時浪費時間

NodeJS的架構(gòu) - 單線程事件循環(huán)

NodeJS不遵循請求/響應(yīng)多線程無狀態(tài)模型。 它采用單線程與事件循環(huán)模型。 NodeJS的處理模型主要基于Javascript基于事件的模型和Javascript回調(diào)機制。

因為NodeJS遵循的架構(gòu),它可以非常輕松地處理越來越多的并發(fā)客戶端請求。 在討論這個模型內(nèi)部之前,首先要看下面的圖表。

我試圖設(shè)計這個圖來解釋NodeJS內(nèi)部的每一點。

NodeJS的處理模型主要核心是“事件循環(huán)(Event Loop)”。如果我們理解這一點,那么很容易理解NodeJS的內(nèi)部架構(gòu)的。

單線程事件循環(huán)模型的處理步驟

客戶端發(fā)送請求到Web服務(wù)器

NodeJS的Web服務(wù)器在內(nèi)部維護一個有限的線程池,以便為客戶端請求提供服務(wù)

NodeJS的Web服務(wù)器接收這些請求并將它們放入隊列中。 它被稱為“事件隊列”

NodeJS的Web服務(wù)器內(nèi)部有一個組件,稱為“事件循環(huán)”,它使用無限循環(huán)來接收請求并處理它們。

事件循環(huán)只使用到了一個線程,它是NodeJS的處理模型的核心

事件循環(huán)回去檢查是否有客戶端的請求被放置在事件隊列中。如果沒有,會一直等待事件隊列中存在請求。

如果有,則會從事件隊列中拾取一個客戶端請求:

開始處理客戶端請求

如果該客戶端請求不需要任何阻塞IO操作,則處理所有內(nèi)容,準備響應(yīng)并將其發(fā)送回客戶端

如果該客戶端請求需要一些阻塞IO操作,例如與數(shù)據(jù)庫,文件系統(tǒng),外部服務(wù)交互,那么它將遵循不同的方法:

從內(nèi)部線程池檢查線程可用性

獲取一個線程并將此客戶端請求分配給該線程

該線程負責(zé)接收該請求,處理該請求,執(zhí)行阻塞IO操作,準備響應(yīng)并將其發(fā)送回事件循環(huán)

事件循環(huán)依次將響應(yīng)發(fā)送到相應(yīng)的客戶端

圖表說明:

Client-1, Client-2, ..., Client-n是同時發(fā)送請求到Web服務(wù)器的客戶端應(yīng)用

Web服務(wù)器內(nèi)部維護著一個有限的線程池,線程池中線程數(shù)量為m個

NodeJS的Web服務(wù)器接收到Client-1, Client-2, ..., Client-n的請求后,將請求放入到事件隊列中

NodeJS的事件循環(huán)從隊列中開始拾取這些請求:

事件循環(huán)拾取Client-1的請求Request-1

檢查Client-1 Request-1是否確實需要任何阻塞IO操作,或者需要更多時間來執(zhí)行復(fù)雜的計算任務(wù)

由于此請求是簡單計算和非阻塞IO任務(wù),因此不需要多帶帶的線程來處理它

事件循環(huán)處理該請求所需要的操作,準備其響應(yīng)Response-1

事件循環(huán)發(fā)送Response-1到Client-1

事件循環(huán)拾取Client-2的請求Request-2

檢查Client-2 Request-2是否需要任何阻塞IO操作或花費更多時間來執(zhí)行復(fù)雜的計算任務(wù)

由于此請求是簡單計算和非阻塞IO任務(wù),因此不需要多帶帶的線程來處理它

事件循環(huán)處理該請求所需要的操作,準備其響應(yīng)Response-2

事件循環(huán)發(fā)送Response-2到Client-2

事件循環(huán)拾取Client-n的請求Request-n

檢查Client-n Request-n是否需要任何阻塞IO操作或花費更多時間來執(zhí)行復(fù)雜的計算任務(wù)

由于此請求有非常復(fù)雜的計算或阻塞IO任務(wù),因此事件循環(huán)不會處理此請求

事件循環(huán)從內(nèi)部線程池中獲取線程T-1,并將此Client-n Request-n分配給線程T-1

線程T-1讀取并處理Request-n,執(zhí)行必要的阻塞IO或計算任務(wù),最后準備響應(yīng)Response-n

線程T-1將此Response-n發(fā)送到事件循環(huán)

事件循環(huán)依次將此Response-n發(fā)送到Client-n

此處客戶端請求是對一個或多個JavaScript函數(shù)的調(diào)用,因為JavaScript函數(shù)可以調(diào)用其他函數(shù)或可以利用其回調(diào)函數(shù)性質(zhì)。

此所以每個客戶端的請求處理都看起來向這樣:

例如:

function1(function2,callback1);
function2(function3,callback2);
function3(input-params);

NodeJS的單線程事件循環(huán)的優(yōu)勢

處理越來越多的并發(fā)客戶端請求非常容易

因為事件循環(huán)的存在,即使我們的NodeJS應(yīng)用接收到了越來越多的并發(fā)請求,我們也不需要去新建很多的線程

NodeJS使用到了較少的線程,所以資源和內(nèi)存的使用較少

原文地址: NodeJS Architecture – Single Threaded Event Loop

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100107.html

相關(guān)文章

  • JavaScript線程事件循環(huán)(Event Loop)那些事

    摘要:概述本篇主要介紹的運行機制單線程事件循環(huán)結(jié)論先在中利用運行至完成和非阻塞完成單線程下異步任務(wù)的處理就是先處理主模塊主線程上的同步任務(wù)再處理異步任務(wù)異步任務(wù)使用事件循環(huán)機制完成調(diào)度涉及的內(nèi)容有單線程事件循環(huán)同步執(zhí)行異步執(zhí)行定時器的事件循環(huán)開始 1.概述 本篇主要介紹JavaScript的運行機制:單線程事件循環(huán)(Event Loop). 結(jié)論先: 在JavaScript中, 利用運行至...

    Shisui 評論0 收藏0
  • Nodejs高性能原理(上) --- 異步非阻塞事件驅(qū)動模型

    摘要:使用了一個事件驅(qū)動非阻塞式的模型,使其輕量又高效。的包管理器,是全球最大的開源庫生態(tài)系統(tǒng)。按照這個定義,之前所述的阻塞,非阻塞,多路復(fù)用信號驅(qū)動都屬于同步。 系列文章 Nodejs高性能原理(上) --- 異步非阻塞事件驅(qū)動模型Nodejs高性能原理(下) --- 事件循環(huán)詳解 前言 終于開始我nodejs的博客生涯了,先從基本的原理講起.以前寫過一篇瀏覽器執(zhí)行機制的文章,和nodej...

    yy736044583 評論0 收藏0
  • JS與Node.js中的事件循環(huán)

    摘要:的單線程,與它的用途有關(guān)。特點的顯著特點異步機制事件驅(qū)動。隊列的讀取輪詢線程,事件的消費者,的主角。它將不同的任務(wù)分配給不同的線程,形成一個事件循環(huán),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運行具有setTimeout和Promise的程序時候執(zhí)行結(jié)果不一樣的問題,從而引出了Nodejs的...

    abson 評論0 收藏0
  • nodejs 異步I/O和事件驅(qū)動

    摘要:異步和事件驅(qū)動注本文是對眾多博客的學(xué)習(xí)和總結(jié),可能存在理解錯誤。接觸有兩個月,對的兩大特性一直有點模糊,即異步和事件驅(qū)動。 nodejs 異步I/O和事件驅(qū)動 注:本文是對眾多博客的學(xué)習(xí)和總結(jié),可能存在理解錯誤。請帶著懷疑的眼光,同時如果有錯誤希望能指出。 接觸nodejs有兩個月,對nodejs的兩大特性一直有點模糊,即異步IO和事件驅(qū)動。通過對《深入淺出nodejs》和幾篇博客的閱...

    binaryTree 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<