這篇文章要跟大家介紹的內容是關於淺談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:┌───────────────────────┐ ┌─>│ timers │<p>poll階段:<strong></strong></p>當進入poll階段,並且沒有timers被呼叫的時候,會發生下面的情況:<p></p>(1)如果poll隊列不為空:<p></p>
- Event Loop 將同步的執行poll queue裡的callback(新的I/O事件),直到queue為空或執行的callback到達上線。
- #如果腳本呼叫了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
#由於timer需要從紅黑樹中取出定時器來判斷時間是否到了,時間複雜度為O(lg(n)),故如果想立即非同步執行一個事件,最好不要用setTimeout(func, 0) 。而是使用 process.nextTick() 來完成。
- 分散式Node架構
- 我所了解的Node叢集架構主要分為以下幾個模組:
按我的理解整理了一副圖:
- ##當然,這應該是比較理想狀態下的架構方式。因為雖然 Redis 的讀/寫相當快,但這是因為將資料儲存在記憶體池裡,並在記憶體上進行相關操作。
這對伺服器的記憶體負荷是相當高的,所以通常我們還是會在架構中加入Mysql,如下圖:
- 先解釋一下這張圖:
當用戶資料到來時,先將資料寫入Mysql,Node 需要資料時再去Redis 讀取,若沒有找到再去Mysql 裡面查詢想要的數據,並寫入Redis,下次使用時就可以直接去Redis 裡面查詢了。
加入Mysql 相較於只在Redis 裡讀/寫的好處有: (1)避免了短期內無用的資料寫入Redis,佔用內存,減輕Redis 負擔
(2)在後期需要對資料進行特定查詢、分析的時候(例如分析營運活動用戶漲幅),SQL關係查詢能提供很大的幫助- 當然在應對短時間大流量寫入的時候,我們也可以直接將資料寫入Redis,以達到快速儲存資料、增加伺服器應對流量能力的目的,等流量下去了再單獨將資料寫入Mysql。 簡單介紹完了大體的架構組成,接下來我們來細看每個部分的細節:
流量接入層所做的就是對所有接受的流量進行處理,提供了以下服務:
- 流量緩衝
- #超時偵測
- #與使用者建立連線逾時
- 讀取使用者body逾時
- Nginx(負載平衡、調度) -> Node集群-> Redis(同步狀態)
- 流量接入層
- 分流與轉送
讀取後端回應頭逾時
寫入回應逾時
與使用者長連線逾時
##叢集健康檢查/隔離壞點伺服器
- 隔離壞點伺服器並嘗試修復/重啟,直到該伺服器恢復正常
- 失敗重試機制
- 在請求轉送到某叢集某機器上,返回失敗後,將該請求轉送到該叢集的別的機器,或是跨叢集的機器上進行重試
連線池/會話保持機制
(2)編寫高效能查詢語句,與Redis、Mysql 交互,提高查詢效率
(3)透過Redis 同步叢集裡各個Node 服務的狀態
(4)透過硬體管理平台,管理/監控實體機器的狀態、管理IP位址等(其實這部分工作放在這一層感覺不妥,但我也不知道應該放在哪一層。。。)
(當然這部分我只是粗淺地列列條目,還是需要時間來累積、深入理解)
資料庫層
這一層主要的工作是:
# (1)建立Mysql 並設計相關頁、表格;建立必要的索引、外鍵,提升查詢便利性
(2)部署redis 並向Node 層提供對應介面
相關推薦:
以上是淺談node.js中高並發與分散式叢集的內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器