nodejs服務(wù)內(nèi)存泄露排查過程和優(yōu)化方法
背景
首先項目最初不是自己寫的,項目接手一段時間后才發(fā)現(xiàn)了問題,往往這種情況不能第一時間定位到具體代碼,需要根據(jù)用戶反饋以及工具排查。
剛開始用戶反饋接口卡頓,影響正常使用,我這邊查看日志發(fā)現(xiàn)沒有異常報錯,就嘗試重啟應(yīng)用,重啟后解決問題。
分析問題
我嘗試了以下步驟
- 由于是代理服務(wù),我以為是請求過多,導(dǎo)致服務(wù)日志寫入過多導(dǎo)致,所以我只保留了嚴重錯誤日志,運行一段時間后發(fā)現(xiàn)無效
- 由于前不久做過一次容器化部署,程序跑一段時間后會生成
core.42文件,文件很大,有30G, 該文件是進程崩潰的內(nèi)存和寄存器的快照。我又嘗試不使用docker部署,運行一段時間后發(fā)現(xiàn)無效 - 使用
pm2 list發(fā)現(xiàn)進程的內(nèi)存使用異常高,高達3.4GB,這才發(fā)覺可能是內(nèi)存泄露導(dǎo)致程序崩潰
pm2 list ┌────┬─────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ? │ status │ cpu │ mem │ user │ watching │ ├────┼─────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤ │ 0 │ erra │ default │ 0.6.53 │ cluster │ 30696 │ 2h │ 23 │ online │ 0% │ 3.4gb │ root │ disabled │ └────┴─────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
內(nèi)存泄漏分析
- 利用Node.js內(nèi)置工具: Node.js提供了一些內(nèi)置工具來分析內(nèi)存使用情況,如
--inspect參數(shù)。啟動Node.js應(yīng)用程序時加上該參數(shù),并使用Chrome開發(fā)者工具的Memory選項來觀察內(nèi)存使用情況。
node --inspect --heapsnapshot-signal=SIGUSR2 ./bin/erra.js start
- 打開 chrome://inspect/#devices

- 啟動項目后,先在Menory中創(chuàng)建一個初始的快照

- 然后進行多次操作(根據(jù)項目流程操作),在創(chuàng)建一個快照進行內(nèi)存對比,發(fā)現(xiàn)內(nèi)存翻倍的增加

- 通過 Retained Size 排序,展開頭幾項看看,展開到能看到具體對象或者方法為止


- 通過展開(closure)也可以定位到文件,到此基本可以確定是 proxy-server.js文 件 與proxyReq 對象相關(guān)出現(xiàn)了內(nèi)存泄露,由于我是本地調(diào)試,所以可以通過點擊文件名跳轉(zhuǎn)到源碼處

解決問題
通過代碼發(fā)現(xiàn),確實存在漏洞, 這種情況屬于事件監(jiān)聽器未移除 (由于初版代碼不是自己寫的,不能一眼發(fā)現(xiàn)此處有問題。)

雖然這里可以改成監(jiān)聽事件處理后釋放就可以解決,但是其實這里只需監(jiān)聽一次就行避免頻繁監(jiān)聽并移除

驗證結(jié)果
為保證是否還存在其他問題,需要重復(fù)上面的步驟,重新驗證是否還存在內(nèi)存泄露。經(jīng)過多次模擬操作之后,內(nèi)存穩(wěn)定在 16.6M 左右,確定沒問題后在發(fā)布

結(jié)論
由于代碼可以在本地復(fù)現(xiàn),所以排查過程還是比較順利的。如果是盲排重點從:定時器未清除、事件監(jiān)聽器未移除、未釋放資源 方向入手。
以上就是nodejs服務(wù)內(nèi)存泄露排查過程和優(yōu)化方法的詳細內(nèi)容,更多關(guān)于nodejs服務(wù)內(nèi)存泄露的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
NPM 安裝cordova時警告:npm WARN deprecated minimatch@2.0.10: Pleas
這篇文章主要介紹了NPM 安裝cordova時警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to的相關(guān)資料,需要的朋友可以參考下2016-12-12
nodejs實現(xiàn)遍歷文件夾并統(tǒng)計文件大小
這篇文章主要介紹了nodejs實現(xiàn)遍歷文件夾并統(tǒng)計文件大小,下面使用nodejs的遍歷文件夾文件內(nèi)容,并且讀取所有的文件,并采取排序往大到小的順序進行輸出,需要的朋友可以參考下2015-05-05
NodeJS模塊與ES6模塊系統(tǒng)語法及注意點詳解
這篇文章主要給大家介紹了關(guān)于NodeJS模塊與ES6模塊系統(tǒng)語法及注意點的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01

