目錄
Node特性:高並發" >Node特性:高並發
單執行緒
非同步I/O
事務驅動
資料庫層
首頁 web前端 js教程 淺談node.js中高並發與分散式叢集的內容

淺談node.js中高並發與分散式叢集的內容

Aug 01, 2018 pm 03:54 PM
javascript node.js 分散式部署

這篇文章要跟大家介紹的內容是關於淺談node.js中高並發與分散式集群的內容,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

Node特性:高並發

在解釋node為什麼能夠做到高並發之前,不妨先了解node的其他幾個特性:

單執行緒

我們先來明確一個概念,即:node是單執行緒的,這一點與JavaScript在瀏覽器中的特性相同,並且在node中JavaScript主執行緒與其他執行緒(例如I/O執行緒)是無法共享狀態的。

單一執行緒的好處就是:

  • #不需要像多執行緒一樣去關注執行緒之間的狀態同步問題

  • 沒有執行緒切換所帶來的開銷

  • 沒有死鎖存在

當然單執行緒也有許多壞處:

  • 無法充分利用多核心CPU

  • 大量運算佔用CPU會導致應用程式阻塞(即不適用CPU密集型)

  • 錯誤會引起整個應用的退出

不過在今天看來,這些壞處都已經不再是問題或得到了適當的解決:

(1) 創建進程or 細分實例

關於第一個問題,最直白解決方案就是使用child_process核心模組或cluster:child_process 和net 組合應用程式。我們可以透過在一台多核心伺服器上建立多個進程(通常使用fork操作)來充分利用每個核心,不過要處理好進程間通訊問題。

另一個方案是,我們可以將實體機器分割成多台單核心的虛擬機,並透過pm2等工具,管理多台虛擬機形成一個叢集架構,高效運作所需服務,至於每台機器間的通訊(狀態同步)我這裡先按下不表,在下文的Node分散式架構中再做詳細說明。

(2) 時間片輪轉

關於第二點,我跟小夥伴討論過後認為可以透過時間片輪轉方式,在單線程上模擬多線程,適當減少應用阻塞的感覺(雖然這種方法不會真的像多執行緒那樣節約時間)

(3) 負載平衡、壞點監控/隔離

至於第三點,我跟小夥伴們也討論過,認為主要的痛點就在於node不同於JAVA,它所實現的邏輯是以非同步為主的。

這就導致了node無法像JAVA一樣方便地使用 try/catch 來捕獲並繞過錯誤,因為無法確定非同步任務會何時傳回異常。而在單線程環境下,繞不過錯誤意味著導致應用程式退出,重啟恢復的間隙會導致服務中斷,這是我們不願意看到的。

當然,在伺服器資源豐富的當下,我們可以透過 pm2 或 nginx 這些工具,動態的判斷服務狀態。在服務出錯時隔離壞點伺服器,將請求轉送到正常伺服器上,並重新啟動壞點伺服器以繼續提供服務。這也是Node分散式架構的一部分。

非同步I/O

你可能會問,既然node是單執行緒的,事件全部在一個執行緒上處理,那不是應該效率很低、與高並發相悖嗎?

恰恰相反,node的效能很高。原因之一是node具有非同步I/O特性,每當有I/O請求發生時,node會提供給該請求一個I/O執行緒。然後node就不管這個I/O的操作過程了,而是繼續執行主執行緒上的事件,只需要在該請求返回回呼時在處理即可。也就是node省去了許多等待請求的時間。

這也是node支援高並發的重要原因之一

實際上不光是I/O操作,node的絕大多數操作都是以這種非同步的方式進行的。它就像是組織者,無需事必躬親,只需要告訴成員們如何正確的進行操作並接受反饋、處理關鍵步驟,就能使得整個團隊高效運作。

事務驅動

你可能又要問了,node怎麼知道請求回傳了回調,又應該何時去處理這些回調呢?

答案是node的另一個特性:事務驅動,也就是主執行緒透過event loop事件循環觸發的方式來執行程式

##這是node支持高並發的另一個重要原因

圖解node環境下的Event loop:

1

2

   ┌───────────────────────┐

┌─>│        timers         │<p>poll階段:<strong></strong></p>當進入poll階段,並且沒有timers被呼叫的時候,會發生下面的情況:<p></p>(1)如果poll隊列不為空:<p></p>

登入後複製
  • Event Loop 將同步的執行poll queue裡的callback(新的I/O事件),直到queue為空或執行的callback到達上線。

(2)如果poll隊列為空:

  • #如果腳本呼叫了setImmediate(), Event Loop將會結束poll階段並且進入到check階段執行setImmediate()的回呼。

  • 如果腳本沒有被setImmediate()調用,Event Loop將會等待回呼(新的I/O事件)被加入到佇列中,然後立即執行它們。

當進入到poll階段,並且呼叫了timers的話,會發生下面的情況:

  • 一旦poll queue是空的話,Event Loop會檢查是否timers, 如果有1個或多個timers時間已經到達,Event Loop將會回到timer階段並執行那些timer的callback(即進入到下一次tick)。

優先:

Next Tick Queue > MicroTask Queue

setTimeout、setInterval > setImmediate

淺談node.js中高並發與分散式叢集的內容

淺談node.js中高並發與分散式叢集的內容


淺談node.js中高並發與分散式叢集的內容#由於timer需要從紅黑樹中取出定時器來判斷時間是否到了,時間複雜度為O(lg(n)),故如果想立即非同步執行一個事件,最好不要用setTimeout(func, 0) 。而是使用 process.nextTick() 來完成。

    分散式Node架構
  • 我所了解的Node叢集架構主要分為以下幾個模組:
    • Nginx(負載平衡、調度) -> Node集群-> Redis(同步狀態)
    • 按我的理解整理了一副圖:

    • ##當然,這應該是比較理想狀態下的架構方式。因為雖然 Redis 的讀/寫相當快,但這是因為將資料儲存在記憶體池裡,並在記憶體上進行相關操作。
    • 這對伺服器的記憶體負荷是相當高的,所以通常我們還是會在架構中加入Mysql,如下圖:

    • 先解釋一下這張圖:

      當用戶資料到來時,先將資料寫入Mysql,Node 需要資料時再去Redis 讀取,若沒有找到再去Mysql 裡面查詢想要的數據,並寫入Redis,下次使用時就可以直接去Redis 裡面查詢了。

    • 加入Mysql 相較於只在Redis 裡讀/寫的好處有:
    • (1)避免了短期內無用的資料寫入Redis,佔用內存,減輕Redis 負擔

    • (2)在後期需要對資料進行特定查詢、分析的時候(例如分析營運活動用戶漲幅),SQL關係查詢能提供很大的幫助
  • 當然在應對短時間大流量寫入的時候,我們也可以直接將資料寫入Redis,以達到快速儲存資料、增加伺服器應對流量能力的目的,等流量下去了再單獨將資料寫入Mysql。

    簡單介紹完了大體的架構組成,接下來我們來細看每個部分的細節:
    • 流量接入層
    • 流量接入層所做的就是對所有接受的流量進行處理,提供了以下服務:

  • 流量緩衝

    • 分流與轉送
    • #超時偵測

  • #與使用者建立連線逾時

  • 讀取使用者body逾時

連線後端逾時

讀取後端回應頭逾時淺談node.js中高並發與分散式叢集的內容

寫入回應逾時

  • 與使用者長連線逾時

  • ##叢集健康檢查/隔離壞點伺服器

  • 隔離壞點伺服器並嘗試修復/重啟,直到該伺服器恢復正常
  • 失敗重試機制
  • 在請求轉送到某叢集某機器上,返回失敗後,將該請求轉送到該叢集的別的機器,或是跨叢集的機器上進行重試

  • 連線池/會話保持機制

#對於延遲敏感使用者使用連線池機制,減少建立連接的時間

###安全防護#############資料分析############當轉送到各個產品線後就到了負載層工作的時候了:將請求根據情況轉發到各地機房######################當然,這個平台並不止轉發這一個功能,你可以把它理解為一個大型的私有雲系統,提供以下服務:############文件上傳/服務線上部署############線上配置修改############設定定時任務#############線上系統監控/日誌列印服務############線上實例管理############鏡像中心#############等等...############Node叢集層######這一層主要的工作是:######(1)編寫可靠的Node 程式碼,為需求提供後端服務###

(2)編寫高效能查詢語句,與Redis、Mysql 交互,提高查詢效率

(3)透過Redis 同步叢集裡各個Node 服務的狀態

(4)透過硬體管理平台,管理/監控實體機器的狀態、管理IP位址等(其實這部分工作放在這一層感覺不妥,但我也不知道應該放在哪一層。。。)

(當然這部分我只是粗淺地列列條目,還是需要時間來累積、深入理解)

資料庫層

這一層主要的工作是:

# (1)建立Mysql 並設計相關頁、表格;建立必要的索引、外鍵,提升查詢便利性

(2)部署redis 並向Node 層提供對應介面

相關推薦:

vue如何使用axios請求後端資料

#對Vue中表單輸入綁定和元件基礎的分析

以上是淺談node.js中高並發與分散式叢集的內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
Linux中如何建構4塊虛擬碟來搭建分散式MinIO叢集? Linux中如何建構4塊虛擬碟來搭建分散式MinIO叢集? Feb 10, 2024 pm 04:48 PM

由於最近剛開始負責物件儲存相關係統的建置與穩定性維運,作為一個「物件儲存」的新手,需要加強這塊的學習。由於公司目前採用MinIO來建構公司的對象儲存體系,後續我會逐步將自己關於MinIO的學習經驗分享出來,歡迎大家持續關注。本文主要是介紹如何在測試環境中建構MinIO,這也是建構MinIO學習環境最基本的步驟。 1.準備實驗環境使用OracleVMVirtualBox虛擬機,安裝一個最小版本的Linux,然後添加4塊虛擬盤,用於充當MinIO的虛擬盤。實驗環境如下:接下來跟大家簡單介紹一下

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

See all articles