ajax 高并发请求,理解node.js处理高并发请求原理
很少分享技術(shù)文章,寫的不好的地方請大家多多指教,本文是自己對于node.js的一些見解,如有紕漏請在評論區(qū)交流。
高并發(fā)策略
通常高并發(fā)的解決方案就是提供多線程模型,服務(wù)器為每個客戶端請求分配一個線程,使用同步 I/O,系統(tǒng)通過線程切換來彌補同步I/O調(diào)用的時間開銷。
但是當(dāng)并發(fā)請求越多創(chuàng)建的線程也越多,這樣創(chuàng)建、銷毀線程以及在線程間切換所需的開銷也是非常大的。
Node.js采用了單線程模型來處理,不會為每個請求分配一個線程,而是用一個主線程處理所有的請求,然后對I/O操作進行異步處理,避開了創(chuàng)建、銷毀線程以及在線程間切換所需的開銷和復(fù)雜性。所以這就是為什么node.js適合IO密集型任務(wù)而不適合計算密集型任務(wù)
node.js 異步IO
異步IO是指操作系統(tǒng)提供的IO(數(shù)據(jù)進出)的能力,比如:磁盤的讀寫,DNS的查詢,數(shù)據(jù)庫的連接,網(wǎng)絡(luò)請求的處理,等等;線程發(fā)出IO操作指令,然后就可以去做別的事情了(線程不需要等待),所有操作完成后再執(zhí)行回調(diào)。
libuv 的IO線程池
nodejs中的異步I/O是通過底層的libuv提供的多線程的線程池來完成的。所以Node.js 的單線程僅僅是指 JavaScript 運行在單線程中,而并非 Node.js 是單線程。
IO線程執(zhí)行IO操作時,會調(diào)用一個系統(tǒng)函數(shù),生成一個請求包向內(nèi)核傳遞,內(nèi)核知道將這個I/O操作發(fā)送給哪個硬件設(shè)備。異步IO同時會傳入一個回調(diào)函數(shù)隨著請求包傳遞給設(shè)備驅(qū)動程序,然后IO線程返回線程池執(zhí)行下一個IO事件。當(dāng)異步I/O請求完成時,設(shè)備驅(qū)動程序就會生成一個I/O完成包,會由IO線程提取完成I/O的請求包,并將之前的回調(diào)函數(shù)推入node.js的task Queue中,等待事件循環(huán)將它推入主線程的執(zhí)行棧執(zhí)行。
node.js 事件循環(huán)(event loop)
每當(dāng)我們運行一個node.js程序時,就會自動創(chuàng)建一個主線程。這個線程是執(zhí)行js代碼的唯一地方。在主線程內(nèi)部,會生成了一個叫事件循環(huán)的東西。這個循環(huán)的作用是調(diào)度我們主線程在哪個時間點應(yīng)該執(zhí)行的操作。
運行程序后不會立即生成事件循環(huán)。它會在整個程序執(zhí)行完后運行
Node.js 基本上所有的事件機制都是用設(shè)計模式中觀察者模式實現(xiàn)。事件就是主題,注冊到這個事件的回調(diào)函數(shù)就是觀察者
通過上圖簡單講一下node.js的事件循環(huán),當(dāng)程序執(zhí)行到異步事件時,比如計時器(setTimeout等),promise, io請求等,會將事件推入事件隊列。
如果是IO操作,事件循環(huán)會將事件推給異步IO線程池,完成返回回調(diào)函數(shù)到task Queue, 非IO操作(setTimout等)會調(diào)用操作系統(tǒng)API執(zhí)行,然后返回到callback quque. 然后根據(jù)事件循環(huán)的不同階段從queue中取出callback函數(shù)推入主線程的執(zhí)行棧中執(zhí)行。
至于事件循環(huán)的階段不是本文的重點,可以參考官網(wǎng)event loop指南這里就不細(xì)講了。
如果有疑問請在評論區(qū)留言交流!
總結(jié)
以上是生活随笔為你收集整理的ajax 高并发请求,理解node.js处理高并发请求原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV.js 快速入门指南
- 下一篇: 2021年衢州高考的成绩查询,2021年