搜尋
首頁web前端js教程追蹤 Node.js 中的高記憶體使用率

在本文中,我將分享我在 Node.js 中追蹤和修復高記憶體使用率的方法。

內容

  • 上下文
  • 方法
    • 理解程式碼
    • 單獨複製問題
    • 從暫存服務擷取設定檔
    • 驗證修復
  • 結果
  • 結論

情境

最近我收到了一張標題為「修復庫 x 中的記憶體洩漏問題」的票證。該描述包括一個 Datadog 儀表板,其中顯示了十幾個因記憶體使用率過高並最終因 OOM(記憶體不足)錯誤而崩潰的服務,並且它們都有共同的 x 庫。

我最近才接觸到程式碼庫(不到 2 週),這使得這項任務充滿挑戰性,也值得分享。

我開始使用兩個訊息:

  • 有一個所有服務都使用的函式庫導致記憶體使用率很高,它涉及到redis(庫的名稱中包含redis)。
  • 受影響的服務清單。

以下是連結到票證的儀表板:

Tracking down high memory usage in Node.js

服務在 Kubernetes 上運行,很明顯,服務會隨著時間的推移積累內存,直到達到內存限制、崩潰(回收內存)並重新啟動。

方法

在本節中,我將分享我如何處理手頭上的任務,找出高記憶體使用率的罪魁禍首並隨後修復它。

理解程式碼

由於我對程式碼庫相當陌生,我首先想了解程式碼、相關函式庫的作用以及它應該如何使用,希望透過這個過程可以更容易地識別問題。不幸的是,沒有適當的文檔,但透過閱讀程式碼和搜尋服務如何利用該庫,我能夠理解它的要點。它是一個圍繞 redis 流的庫,並為事件生成和消費提供方便的介面。花了一天半的時間閱讀程式碼,由於程式碼結構和複雜性(許多我不熟悉的類別繼承和rxjs),我無法掌握所有細節以及資料如何流動。

因此我決定暫停閱讀,並在觀察程式碼運行情況並收集遙測資料的同時嘗試發現問題。

單獨複製該問題

由於沒有可用的分析資料(例如連續分析)可以幫助我進一步調查,因此我決定在本地複製該問題並嘗試捕獲記憶體配置檔案。

我發現了幾種在 Node.js 中捕獲記憶體設定檔的方法:

  • 使用堆快照
  • 使用堆分析器
  • JavaScript 效能分析
  • Clinic.js

由於不知道去哪裡尋找,我決定運行我認為是庫中最「資料密集」的部分,即 redis 流生產者和消費者。我建立了兩個簡單的服務,它們可以產生和使用來自 redis 流的數據,然後我繼續捕獲記憶體配置文件並比較一段時間內的結果。不幸的是,在對服務產生負載並比較配置文件幾個小時後,我無法發現這兩個服務中任何一個服務的記憶體消耗有任何差異,一切看起來都很正常。該庫公開了一系列不同的介面以及與 Redis 流交互的方式。我很清楚,複製該問題比我預期的要複雜得多,尤其是在我對實際服務的特定領域知識有限的情況下。

所以問題是,如何找到合適的時機和條件來捕獲記憶體洩漏?

從暫存服務捕獲設定檔

如前所述,捕獲記憶體設定檔的最簡單、最方便的方法是對受影響的實際服務進行連續分析,但我沒有這個選項。我開始研究如何至少利用我們的暫存服務(它們面臨同樣的高記憶體消耗),這將使我無需額外的努力即可捕獲所需的資料。

我開始尋找一種將 Chrome DevTools 連接到其中一個正在運行的 Pod 並隨著時間的推移捕獲堆快照的方法。我知道記憶體洩漏發生在暫存階段,因此,如果我能夠捕獲該數據,我希望能夠至少發現一些熱點。令我驚訝的是,有一種方法可以做到這一點。

執行此操作的過程

  • 透過向 pod 上的節點進程發送 SIGUSR1 訊號來啟用 pod 上的 Node.js 偵錯器。
kubectl exec -it <nodejs-pod-name> -- kill -SIGUSR1 <node-process-id>
</node-process-id></nodejs-pod-name>

更多關於 Signal Events 中的 Node.js 訊號

如果成功,您應該會看到來自服務的日誌:

Debugger listening on ws://127.0.0.1:9229/....
For help, see: https://nodejs.org/en/docs/inspector
  • 透過運行在本地公開調試器正在偵聽的端口
kubectl port-forward <nodejs-pod-name> 9229
</nodejs-pod-name>
  • 將 Chrome Devtools 連接到您在先前步驟中啟用的偵錯器。造訪 chrome://inspect/,您應該在目標清單中看到您的 Node.js 進程:

Tracking down high memory usage in Node.js

如果沒有,請確保您的目標發現設定正確設定

Tracking down high memory usage in Node.js

現在您可以開始捕捉逾時快照(時間段取決於發生記憶體洩漏所需的時間)並進行比較。 Chrome DevTools 提供了一種非常方便的方法來做到這一點。

您可以在記錄堆快照中找到有關記憶體快照和 Chrome 開發工具的更多資訊

建立快照時,主執行緒中的所有其他工作都會停止。根據堆內容,甚至可能需要一分多鐘的時間。快照內建在記憶體中,因此它可以使堆大小加倍,從而導致填滿整個內存,然後使應用程式崩潰。

如果您要在生產中取得堆疊快照,請確保從中取得快照的進程可以崩潰,而不會影響應用程式的可用性。

來自 Node.js 文件

回到我的例子,選擇兩個快照進行比較並按增量排序,我得到了您在下面看到的內容。

Tracking down high memory usage in Node.js

我們可以看到最大的正增量發生在字串建構子上,這意味著該服務在兩個快照之間創建了許多字串,但它們仍在使用中。現在的問題是它們是在哪裡創建的以及誰在引用它們。幸運的是,捕獲的快照包含了這些信息,也稱為 Retainers。

Tracking down high memory usage in Node.js

在深入研究快照和永不縮小的字串列表時,我注意到一種類似於 id 的字串模式。單擊它們,我可以看到引用它們的鏈對象 - 又稱保留器。這是一個名為 sendEvents 的數組,其類別名稱是我可以從庫程式碼中識別出來的。哎呀,我們找到了罪魁禍首,一個不斷增長的 id 列表,到目前為止我認為這些列表從未被發布過。我超時拍攝了一堆快照,這是唯一一個不斷重新出現為具有較大正增量的熱點的地方。

驗證修復情況

有了這些訊息,我不需要嘗試完全理解程式碼,而是需要關注陣列的用途、何時填充和何時清除。在一個地方,程式碼將項目推送到數組,而在另一個地方,程式碼將項目彈出,這縮小了修復的範圍。

可以安全地假設數組在應該清空的時候沒有被清空。跳過程式碼的細節,基本上發生的事情是這樣的:

  • 該程式庫公開了用於消費、產生事件或產生和消費事件的介面。
  • 當它既消耗又產生事件時,它需要追蹤進程本身產生的事件,以便跳過它們而不重新消耗它們。 sendEvents 在生成時被填充,並在嘗試使用時被清除,它會跳過訊息。

你能看出這是怎麼回事嗎? ?當服務僅使用該程式庫來產生事件時,sentEvents 仍會填入所有事件,但沒有程式碼路徑(使用者)用於清除它。

我修補了程式碼以僅追蹤生產者、消費者模式上的事件並部署到登台。即使存在暫存負載,很明顯該補丁也有助於減少高記憶體使用率,並且沒有引入任何回歸。

結果

當修補程式部署到生產環境時,記憶體使用量大幅減少,服務的可靠性得到提高(不再出現 OOM)。

Tracking down high memory usage in Node.js

一個很好的副作用是處理相同流量所需的 Pod 數量減少了 50%。

Tracking down high memory usage in Node.js

結論

對我來說,這是一個很好的學習機會,可以追蹤 Node.js 中的記憶體問題並進一步熟悉可用的工具。

我認為最好不要詳細討論每個工具的細節,因為這值得單獨發表一篇文章,但我希望這對於任何有興趣了解更多有關此主題或面臨類似問題的人來說是一個很好的起點。

以上是追蹤 Node.js 中的高記憶體使用率的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

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

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

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

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

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

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

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

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

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

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

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

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

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

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

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

See all articles

熱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

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

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

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

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境