nodejs 是單線程且支持高並發的腳本語言( node 異步 I/O )
node 的優點:I/O 密集型處理是 node 的強項,因為 node 的 I/O 請求都是異步的( sql 查詢請求、文件流操作操作請求、http請求... )
異步
發出操作指令,然后就可以去做別的事情了(主線程無需等待),所有操作完成后執行回調
let a = 1; // step1:定義變量 // step2:發出指令,然后把回調函數加入事件隊列(回調函數並沒有執行) setTimeout(() => { console.log(a); }, 0) a = 2; // step3:賦值,回調函數沒有執行 // step4:發出指令,然后把回調函數加入異步隊列(回調函數並沒有執行) setTimeout(() => { console.log(a); }, 0) a = 3; // step5:賦值,回調函數沒有執行 // 當所有代碼執行完畢,cpu空閑下來了,就會開始遍歷執行事件隊列里面的回調函數 // 最后輸出:3 3
異步 I/O 的 node 為什么可以支持高並發?
I/O 操作由 node 的工作線程執行( nodejs 底層的 libuv 是多線程的線程池用來並行 io 操作)
主線程不需要等待結果返回,發出指令后就去執行其他事務
nodejs 在執行 JavaScript 時,內存受到 v8 限制,64位 約為 1.4g,32位 0.7g
所有 js 對象是通過堆分配,查看 process.memoryUsage ()
I/O 操作開啟了多線程,但是所有線程都是基於 node 服務進程開啟的,並不能充分利用 cpu 資源
限制內存原因:垃圾回收機制執行時,js 線程會暫停執行(避免 JS 應用邏輯與垃圾回收器看到的不一樣),大量的堆內存回收嚴重影響性能
解決方法:pm2 是一個帶有負載均衡(分攤到多個操作單元上進行執行)功能的 Node 應用的進程管理器
cpu核數與線程之間的關系
在過去單CPU時代,單任務在一個時間點只能執行單一程序。之后發展到多任務階段,計算機能在同一時間點並行執行多任務或多進程。雖然並不是真正意義上的“同一時間點”,而是多個任務或進程共享一個CPU,並交由操作系統來完成多任務間對CPU的運行切換,以使得每個任務都有機會獲得一定的時間片運行。而現在多核CPU的情況下,同一時間點可以執行多個任務,具體到這個任務在CPU哪個核上運行跟操作系統和CPU本身的設計相關
node的缺點:不擅長cpu密集型的操作
// 什么是cpu密集型操作(復雜的運算、圖片的操作) // 示例 for (let i = 0; i < 100000000; i++) { console.log(i); }
nodejs是單線程的,進行密集型的運算會導致主線程掛起