亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

Node.js異步I/O學習筆記

2019-11-20 13:57:50
字體:
來源:轉載
供稿:網友

“異步”這個名詞的大規模流行是在Web 2.0浪潮中,它伴隨著Javascript和AJAX席卷了Web。但在絕大多數高級編程語言中,異步并不多見。PHP最能體現這個特點:它不僅屏蔽了異步,甚至連多線程也不提供,PHP都是以同步阻塞的方式來執行。這樣的優點利于程序猿順序編寫業務邏輯,但在復雜的網絡應用中,阻塞導致它無法更好地并發。

在服務器端,I/O非常昂貴,分布式I/O更加昂貴,只有后端能快速響應資源,前端的體驗才能變得更好。Node.js是首個將異步作為主要編程方式和設計理念的平臺,伴隨著異步I/O的還有事件驅動和單線程,它們構成Node的基調。本文將介紹Node是如何實現異步I/O的。

1. 基本概念

“異步”與“非阻塞”聽起來似乎是一回事,從實際效果而言,這兩者都達到了并行的目的。但是從計算機內核I/O而言,只有兩種方式:阻塞與非阻塞。因此異步/同步和阻塞/非阻塞實際上是兩回事。

1.1 阻塞I/O與非阻塞I/O

阻塞I/O的一個特點是調用之后一定要等到系統內核層面完成所有操作后,調用才結束。以讀取磁盤上的一個文件為例,系統內核在完成磁盤尋道、讀取數據、復制數據到內存中后,這個調用才結束。

阻塞I/O造成CPU等待I/O,浪費等待時間,CPU的處理能力不能得到充分利用。非阻塞I/O的特點就是調用之后會立即返回,返回后CPU的時間片可以用來處理其他事務。由于完整的I/O并沒有完成,立即返回的并不是業務層期待的數據,而僅僅是當前調用的狀態。為了獲取完整的數據,應用程序需要重復調用I/O操作來確認是否完成(即輪詢)。輪詢技術要以下幾種:

1.read:通過重復調用來檢查I/O狀態,是最原始性能最低的一種方式
2.select:對read的改進,通過對文件描述符上的事件狀態來進行判斷。缺點是文件描述符最大的數量有限制
3.poll:對select的改進,采用鏈表的方式避免最大數量限制,但描述符較多時,性能還是十分低下
4.epoll:進入輪詢時若沒有檢查到I/O事件,將會進行休眠,直到事件發生將其喚醒。這是當前Linux下效率最高的I/O事件通知機制

輪詢滿足了非阻塞I/O確保獲取完整數據的需求,但對于應用程序而言,它仍然只能算作一種同步,因為依然需要等待I/O完全返回。等待期間,CPU要么用于遍歷文件描述符的狀態,要么用于休眠等待事件發生。

1.2 理想與現實中的異步I/O

完美的異步I/O應該是應用程序發起非阻塞調用,無需通過輪詢就可以直接處理下一個任務,只需在I/O完成后通過信號或回調將數據傳遞給應用程序即可。

現實中的異步I/O在不同操作系統下有不同的實現,如*nix平臺采用自定義的線程池,Windows平臺采用IOCP模型。Node提供了libuv作為抽象封裝層來封裝平臺兼容性判斷,并保證上層Node與下層各平臺異步I/O的實現各自獨立。另外需要強調的是我們經常提到Node是單線程的,這僅僅是指Javascript的執行在單線程中,實際在Node內部完成I/O任務的都另有線程池。

2. Node的異步I/O

2.1 事件循環

Node的執行模型實際上是事件循環。在進程啟動時,Node會創建一個無限循環,每一次執行循環體的過程成為一次Tick。每個Tick過程就是查看是否有事件等待處理,如果有則取出事件及其相關的回調函數,若存在關聯的回調函數則執行它們,然后進入下一個循環。如果不再有事件處理,就退出進程。

2.2 觀察者

每個事件循環中有若干個觀察者,通過向這些觀察者詢問來判斷是否有事件要處理。事件循環是一個典型的生產者/消費者模型。在Node中,事件主要來源于網絡請求、文件I/O等,這些事件都有對應的網絡I/O觀察者、文件I/O觀察者等,事件循環則從觀察者那里取出事件并處理。

2.3 請求對象

從Javascript發起調用到內核執行完I/O操作的過渡過程中,存在一種中間產物,叫做請求對象。以最簡單的Windows下fs.open()方法(根據指定路徑和參數去打開一個文件并得到一個文件描述符)為例,從JS調用到內建模塊通過libuv進行系統調用,實際上是調用了uv_fs_open()方法。在調用過程中,創建了一個FSReqWrap請求對象,從JS層傳入的參數和方法都封裝在這個請求對象中,其中我們最為關注的回調函數被設置在這個對象的oncompete_sym屬性上。對象包裝完畢后,將FSReqWrap對象推入線程池中等待執行。

至此,JS調用立即返回,JS線程可以繼續執行后續操作。當前的I/O操作在線程池中等待執行,這就完成了異步調用的第一階段。

2.4 執行回調

回調通知是異步I/O的第二階段。線程池中的I/O操作調用完畢后,會將獲取的結果儲存起來,然后通知IOCP當前對象操作已完成,并將線程歸還線程池。在每次Tick的執行中,事件循環的I/O觀察者會調用相關的方法檢查線程池中是否有執行完的請求,如果存在,會將請求對象加入到I/O觀察者的隊列中,然后將其當做事件處理。

3. 非I/O的異步API

Node中還存在一些與I/O無關的異步API,例如定時器setTimeout()、setInterval(),立即異步執行任務的process.nextTick()和setImmdiate()等,這里略微介紹一下。

3.1 定時器API

setTimeout()和setInterval()瀏覽器端的API是一致的,它們的實現原理與異步I/O類似,只是不需要I/O線程池的參與。調用定時器API創建的定時器會被插入到定時器觀察者內部的一棵紅黑樹中,每次事件循環的Tick都會從紅黑樹中迭代取出定時器對象,檢查是否超過定時時間,若超過就形成一個事件,回調函數立即被執行。定時器的主要問題在于它的定時時間并非特別精確(毫秒級,在容忍范圍內)。

3.2 立即異步執行任務API

在Node出現之前,很多人也許為了立即異步執行一個任務,會這樣調用:

復制代碼 代碼如下:

setTimeout(function() {
    // TODO
}, 0);

由于事件循環的特點,定時器的精確度不夠,而且采用定時器需要使用紅黑樹,各種操作時間復雜度為O(log(n))。而process.nextTick()方法只會將回調函數放入隊列中,在下一輪Tick時取出執行,復雜度為O(1)更為高效。

此外還有一個setImmediate()方法和上述方法類似,都是將回調函數延遲執行。不過前者的優先級要比后者高,這是因為事件循環對觀察者的檢查是有先后順序的。另外,前者的回調函數保存在一個數組中,每輪Tick會將數組中的所有回調函數全部執行完;后者結果保存在鏈表中,每輪Tick只會執行一個回調函數。

4. 事件驅動與高性能服務器

前面以fs.open()為例闡述了Node如何實現異步I/O。事實上對網絡套接字的處理,Node也應用了異步I/O,這也是Node構建Web服務器的基礎。經典的服務器模型有:

1.同步式:一次只能處理一個請求,其余請求都處于等待狀態
2.每進程/每請求:為每個請求啟動一個進程,但系統資源有限,不具備擴展性
3.每線程/每請求:為每個請求啟動一個線程。線程比進程要輕量,但每個線程都占用一定內存,當大并發請求到來時,內存很快就會用光

著名的Apache采用的就是每線程/每請求的形式,這也是它難以應對高并發的原因。Node通過事件驅動方式處理請求,可以省掉創建和銷毀線程的開銷,同時操作系統在調度任務時因為線程較少,上下文切換的代價也很低。即使在大量連接的情況下,Node也能有條不紊地處理請求。

知名服務器Nginx也摒棄了多線程的方式,采用和Node一樣的事件驅動方式。如今Nginx大有取代Apache之勢。Nginx采用純C編寫,性能較高,但是它僅適合做Web服務器,用于反向代理或負載均衡等。Node可以構建與Nginx相同的功能,也可以處理各種具體業務,自身性能也不錯。在實際項目中,我們可以結合它們各自有點,以達到應用的最佳性能。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内精品久久久久久影视8| 91黑丝在线观看| 欧美在线观看一区二区三区| 亚州精品天堂中文字幕| 红桃av永久久久| 538国产精品一区二区在线| 日韩一区二区欧美| 国产精品色视频| 91av视频在线免费观看| 中文字幕视频在线免费欧美日韩综合在线看| 中文字幕国产日韩| 中文字幕精品久久| 亚洲精品综合精品自拍| 精品国产一区二区三区久久狼黑人| 亚洲女人被黑人巨大进入al| 国产成人综合亚洲| 91国产在线精品| 国内精品久久久久久中文字幕| 久久中文字幕一区| 成人黄色网免费| 日产精品久久久一区二区福利| 国产精品久久久久福利| 亚洲色图第一页| 日韩一区二区三区国产| 精品国产一区久久久| 性色av香蕉一区二区| 欧美洲成人男女午夜视频| 国产亚洲激情视频在线| 国产精品久久久久久久久久99| 亚洲free性xxxx护士hd| 国产精品jvid在线观看蜜臀| 成人国产在线激情| 成人淫片在线看| 国产美女精彩久久| 韩国国内大量揄拍精品视频| 久久精品91久久香蕉加勒比| 国产97在线播放| 亚洲在线观看视频| 91精品久久久久久久久青青| 亚洲一区二区三区四区在线播放| 国内精品中文字幕| 欧美日韩成人在线播放| 俺去亚洲欧洲欧美日韩| 尤物99国产成人精品视频| 91av在线不卡| 成人美女av在线直播| 久久精品中文字幕| 欧美日韩免费在线观看| www国产精品com| 亚洲国产成人91精品| 色婷婷综合久久久久中文字幕1| 亚洲一区二区免费| 亚洲va欧美va国产综合久久| 91精品91久久久久久| 国产欧美日韩中文字幕在线| 亚洲国产精品久久久久秋霞不卡| 粉嫩老牛aⅴ一区二区三区| 国产va免费精品高清在线| 成人精品一区二区三区电影免费| 久久久亚洲欧洲日产国码aⅴ| 668精品在线视频| 久久99视频精品| 成人美女av在线直播| 午夜精品国产精品大乳美女| 欧美韩国理论所午夜片917电影| 欧美日韩国产91| 欧美性视频在线| 国产精品久久久久久久久久久久久久| 欧美在线激情视频| 琪琪亚洲精品午夜在线| 美女性感视频久久久| 亚洲**2019国产| 久久久久久久久综合| 成人国产亚洲精品a区天堂华泰| 精品视频在线播放免| 操91在线视频| 日韩免费中文字幕| 久久99久国产精品黄毛片入口| 精品亚洲国产成av人片传媒| 亚洲成人精品视频在线观看| 欧美性高潮床叫视频| 欧美美女15p| 超碰91人人草人人干| 久久天天躁狠狠躁老女人| 日韩av在线电影网| 美女精品视频一区| 欧美肥臀大乳一区二区免费视频| 国产一区二区在线免费视频| 亚洲电影免费观看高清完整版在线| 欧美日韩另类字幕中文| 上原亚衣av一区二区三区| 亚洲天堂成人在线视频| 国产精品7m视频| 亚洲国产精品嫩草影院久久| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲欧美资源在线| 欧美亚州一区二区三区| 国产原创欧美精品| 影音先锋日韩有码| 日韩av一区二区在线| 日韩小视频在线观看| 78色国产精品| 亚洲欧美日韩天堂| 国产日韩欧美视频| 九九九热精品免费视频观看网站| 亚洲天堂日韩电影| 欧美wwwwww| 91网在线免费观看| 国产午夜精品视频| 国产欧美一区二区三区在线看| 亚洲大胆美女视频| 日韩av免费在线观看| 国产精品视频一区二区高潮| 国产有码在线一区二区视频| 欧美高清无遮挡| 97精品在线观看| 国产有码在线一区二区视频| 亚洲最新中文字幕| 日韩欧美国产高清91| 日韩在线观看精品| 日韩在线视频免费观看高清中文| 97视频在线免费观看| 国产精品福利片| 九九热这里只有在线精品视| 国产精品尤物福利片在线观看| 欧美xxxx做受欧美.88| 91青草视频久久| 精品国产91久久久久久| 精品久久久中文| 欧美激情精品在线| 欧美性猛交xxxx偷拍洗澡| 日韩经典中文字幕在线观看| 欧洲亚洲免费在线| 欧美成人免费一级人片100| 国内精品久久久久久久久| 国产mv久久久| 国产精品久久久久久av下载红粉| 亚洲日韩第一页| 欧美日韩在线视频一区| 日韩av网址在线观看| 国产精品久久久久久久9999| 91手机视频在线观看| 色综合老司机第九色激情| 亚洲影院高清在线| 亚洲午夜女主播在线直播| 亚洲第一综合天堂另类专| 久久免费视频在线观看| 日韩一区二区欧美| 欧美性xxxxxxx| 久久久久久久久久久免费精品| 欧美日韩国产一区二区| 国产日本欧美一区二区三区在线| 亚洲一区二区久久久久久| 国产精品福利在线| 欧美另类极品videosbestfree| 日韩精品极品在线观看| 色七七影院综合| 亚洲精品丝袜日韩| 欧美日韩另类视频| 精品视频在线观看日韩| 亚洲加勒比久久88色综合| 红桃视频成人在线观看| 国产精品1区2区在线观看| 精品久久久久久久大神国产|