Nodejs基礎(chǔ)知識點總結(jié)

Node的特點:異步IO、事件和回調(diào)函數(shù)、單線程、跨平臺(libuv)

1. nodejs模塊機制

  1. 模塊定義:module、require、exports
  2. 模塊實現(xiàn):
    a. 優(yōu)先從緩存中加載:部分和核心模塊和引入過的模塊都會進行緩存,緩存的是編譯和執(zhí)行后的對象。
    b. 路徑分析和文件定位:分析模塊類型是核心模塊,路徑形式的模塊、自定義模塊,不同類型查找方式不同。
    c. 模塊編譯:編譯過程中,node對js文件進行了頭尾包裝,包裝后的代碼會通過vm原生模塊的方法進行執(zhí)行等。
  3. 模塊的聯(lián)系機制:包和npm

2. 異步IO

  1. 優(yōu)勢:相比同步IO,減少資源獲取等待時間,避免cpu等待浪費;相比多線程模式,不存在狀態(tài)同步、死鎖等問題。
  2. 異步IO流程
    a. 事件循環(huán):node會創(chuàng)建一個類似while的循環(huán),每次執(zhí)行查看是否有待處理的時間,如果有取出來事件和相關(guān)回調(diào)函數(shù)并執(zhí)行。然后進入下個循環(huán)直到不再有事件處理。
    b. 觀察者:判斷是否有事件需要處理。每個事件循環(huán)有一個或多個觀察者。
    c. 請求對象:js發(fā)起調(diào)用到內(nèi)核執(zhí)行完io操作的過程中存在的中間產(chǎn)物。
    d. 執(zhí)行回調(diào):請求對象組裝完成會放入IO線程池等待調(diào)用。
    整個異步IO流程.jpg
  3. 非IO的異步API
    a. 定時器: setTimeout 單次,setIntesrval多次。定時器創(chuàng)建到定時器觀察者內(nèi)部,每次事件循環(huán)執(zhí)行會迭代取出定時器對象,檢查超過定時時間,就形成事件,其回調(diào)函數(shù)立即執(zhí)行。
  4. node服務(wù)器高性能原因:node通過事件驅(qū)動方式處理請求,無需為每個請求分配單獨的進程或線程,沒有創(chuàng)建或銷毀進程的開銷,同時操作系統(tǒng)在調(diào)度任務(wù)時,由于線程較少,受到線程切換上下文影響較小,能使服務(wù)器在面對大量請求時,依然保持高性能。

3. 異步編程

  1. 事件發(fā)布訂閱:emitter.on()、emitter.emit()
  2. Promise:resolve成功處理,reject 錯誤處理
  3. async await
  4. 解決單線程中大量計算問題:child process

4. 內(nèi)存控制

  1. v8垃圾回收和內(nèi)存限制
    a. v8內(nèi)存限制:64位系統(tǒng)下1.4GB,32位系統(tǒng)下0.7GB,可以通過命令更改內(nèi)存。做內(nèi)存限制的原因是垃圾回收耗時長,并且會引起js線程暫停,應(yīng)用的性能和響應(yīng)能力會直線下降。
    b. v8對象分配:v8中的js對象都分配在堆中
    c. v8垃圾回收機制
  1. 分代式垃圾回收機制
    新生代中的對象為存活時間較短的對象,老生代中的對象是存活時間較長或常駐內(nèi)存的對象。


    v8內(nèi)存分代.png
  2. Scavenge算法
    在分代的基礎(chǔ)上,新生代中的對象主要通過scavenge算法進行垃圾回收。算法采用復制的方式實現(xiàn)垃圾回收。
    算法將新生代堆內(nèi)存一分為二,一個處于空閑(to),一個處于使用(from)。當進行對象分配時,先在from中進行分配。開始進行來及回收時將from中存活對象復制到to,非存活對象釋放,然后from和to角色互換。
    當一個對象多次復制依然存活,或to空間使用超過25%,會移動到老生代進行管理。


    V8堆內(nèi)存.png
  3. Mark-sweep(標記清除)&Mark-Compact(標記移動)管理老生代
    Mark-sweep標記堆中所有活著的對象,隨后清理沒有標記的對象。清楚后會出現(xiàn)內(nèi)存不連續(xù)的情況。
    Mark-compact標記死亡對象,在整理過程中將活著的對象往一邊移動,然后清理掉邊界外的內(nèi)存。
  4. 增量標記
    為了降低垃圾回收造成的停頓時間,v8從標記階段,將原本一口氣停頓完成的動作改為增量標記。
  1. 閉包:實現(xiàn)外部作用域訪問內(nèi)部作用域變量的方法叫做閉包。無法立即回收內(nèi)存的情況有全局變量和閉包。
  2. 堆外內(nèi)存:不是v8分配的部分,可以突破v8內(nèi)存限制。

5. Buffer

類似Array對象,操作字節(jié),屬于堆外內(nèi)存。

6. 網(wǎng)絡(luò)編程

node提供了net、dgram、http、https模塊,分別處理tcp、udp、http、https。
網(wǎng)絡(luò)模型.png
  1. 網(wǎng)絡(luò)協(xié)議
    a. HTTP
    應(yīng)用層協(xié)議,無狀態(tài)協(xié)議。tcp以connection為單位進行服務(wù),http以request為單位服務(wù)。http即將connection到request的過程進行了封裝。
    報文頭在報文體發(fā)送之前發(fā)送,一旦開始發(fā)送數(shù)據(jù),設(shè)置header將不再生效。
    b. websocket
    為長鏈接,使用websocket,客戶端和服務(wù)器只需TCP鏈接即可完成雙向通信,在客戶端和服務(wù)器頻繁通信時,無需頻繁斷開鏈接和重發(fā)請求。一旦握手成功,服務(wù)器和客戶端呈現(xiàn)對等效果,都可以接收和發(fā)送信息。
    握手涉及到協(xié)議升級:客戶端建立鏈接時,通過http發(fā)起請求報文,特定協(xié)議頭(Upgrade:websocket;Connection:Upgrade)請求服務(wù)器升級協(xié)議為websocket

  2. 網(wǎng)絡(luò)安全
    a. TLS/SSL

    密鑰
    為公鑰/私鑰結(jié)構(gòu),非對稱加密。每個客戶端和服務(wù)器都有自己的公私鑰。公鑰用來加密數(shù)據(jù),私鑰用來解密數(shù)據(jù)。在建立安全傳輸之前,客戶端和服務(wù)器要交換公鑰。node采用OpenSSL實現(xiàn)TLS/SSL。
    客戶端請求數(shù)據(jù)----服務(wù)器公鑰加密-----(傳輸)----->服務(wù)器私鑰解密
    服務(wù)器返回數(shù)據(jù)----客戶端公鑰加密-----(傳輸)----->客戶端私鑰解密

    數(shù)字證書
    解決“中間人攻擊”。數(shù)字證書中博涵了服務(wù)器名稱和主機名稱、服務(wù)器公鑰、簽名頒發(fā)機構(gòu)名稱等,在建立鏈接之前確認收到的公鑰是來自目標服務(wù)器。

    b. HTTPS服務(wù)
    工作在TLS/SSL上的http

7. WEB服務(wù)

  1. 常用請求方法:get、post(更新)、put(新建)、delete、head
  2. querystring模塊用于處理url ?后的查詢字符串
  3. Cookie常見選項
    a. Expires,utc格式字符串,告訴客戶端cookie什么時候過期
    b. HttpOnly,不允許通過腳本操作cookie值
    c. Secure,為true,在http無效,表示在https鏈接中才被瀏覽器傳遞到服務(wù)器進行驗證。
  4. Session:只存在服務(wù)器
  5. xss漏洞:用戶的輸入沒有被轉(zhuǎn)義,而被直接執(zhí)行。
  6. 添加緩存:
    a. 添加expire或catch-control到報文頭
    b. 設(shè)置ETags
    c. 讓ajax可緩存
  7. 清除緩存,url帶版本號
  8. CSRF(跨站請求偽造),攻擊者偽造成信任用戶攻擊站點,使用token解決。

8. 進程

  1. 多進程架構(gòu) child_process
    child_process.fork(),實現(xiàn)進程的復制,主從模式。父子進程之間創(chuàng)建IPC通道,進行父子進程通信。在系統(tǒng)內(nèi)核層面完成通信,不經(jīng)過實際的網(wǎng)絡(luò)層。
let fork = require('child_process').fork;
let cpus = require('os').cpus();
for (let i = 0; i < cpus.length; i++) {
    // server start
    fork('./worker.js');
}
主從模式.png
  1. cluster
    cluster就是child_process和net模塊的組合應(yīng)用。cluster啟動時,內(nèi)部會啟動TCP服務(wù)器,在cluster.fork()子進程時,將TCP服務(wù)器socket描述符發(fā)送給工作進程。

參考書籍:《深入淺出Nodejs》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容