最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

NodeJs內存占用過高的排查實戰(zhàn)記錄

 更新時間:2021年05月10日 11:34:56   作者:noxxxx  
這篇文章主要給大家介紹了關于NodeJs內存占用過高的排查實戰(zhàn)記錄,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

一次線上容器擴容引發(fā)的排查,雖然最后查出并不是真正的 OOM 引起的,但還是總結記錄一下其中的排查過程,整個過程像是破案,一步步尋找蛛絲馬跡,一步步驗證出結果。

做這件事的意義和必要性個人覺得有這么幾個方面吧:

  1. 從程序員角度講:追求代碼極致,不放過問題,務必保證業(yè)務的穩(wěn)定性這幾個方面
  2. 從資源角度講:就是為了降低無意義的資源開銷
  3. 從公司角度講:降低服務器成本,給公司省錢

環(huán)境:騰訊 Taf 平臺上運行的 NodeJs 服務。

問題起因

最開始是因為一個定時功能上線后,線上的容器自動進行了擴容,由于 NodeJs 服務本身只有一些接口查詢和 socket.io 的功能,一沒大流量,二沒高并發(fā)的一個服務居然需要擴容 8 個容器(一個容器分配的是 2G 的內存),想到這里懷疑是內存泄漏了。同時日志中偶發(fā)的看到內存不足。

擴容原因

問了運維同學查到是由于內存占用到臨界值導致的擴容。

負載情況

首先排除一下是不是因為服務壓力過大導致的內存占用升高,可能這是一種正常的業(yè)務現象。

通過監(jiān)測,發(fā)現流量和 CPU 占用都不是很高,甚至可以說是很低,那么這么高的內存占用是屬于不正常的現象的。

因為是內存原因導致的,而且有逐步持續(xù)上升的現象,所以就聯(lián)想到了內存泄漏這個方向,常用的做法是打印「堆快照」即 heapsnapshot 文件。

進入容器:

go 節(jié)點名稱

進入 NodeJs 項目的文件夾

/usr/local/app/taf/service_name/bin/src

生成快照:

const heapdump = require('heapdump');
heapdump.writeSnapshot('./' + new Date().getTime() + '.heapsnapshot', function(err, filename) {
    console.log('dump written to', filename);
});

受限于容器內使用 lrzsz 命令直接傳輸文件很慢,因此需要使用 scp 命令傳輸到一臺靜態(tài)資源服務器上,可以通過瀏覽器進行下載的。

scp 1620374489828.heapsnapshot username@ip:/data/static/snapshot

對比 heapsnapshot

在服務啟動后,和運行一段時間后的生成兩次快照內容,對比后的排序也只能大致看到 Websocket Socket 這些關鍵字。

進一步展開也無法定位到是否由某個函數引起的。

從快照里面似乎找不到什么線索,由于整個工程的業(yè)務量代碼并不是很大,因此逐行 review 排查,但是似乎也沒有什么異常的寫法會引起 oom,其實業(yè)務代碼小還好,如果是個大工程的話,這種做法沒有性價比,還是需要通過一些診斷手段來排查,而不是直接去 codereview。

反復打印了幾次快照,看了幾遍后,還是看到 websocket 這些字眼,因而考慮到是否是因為 socket 鏈接未釋放導致的問題呢?

Google 關鍵字搜了一下 WebSocket memory leak ,還真有,解決方案是加上 perMessageDeflate ,禁用壓縮。目前低版本的 socket-io 默認是開啟的,于是我加了之后觀察了一段時間的內存占用,并未有明顯的下跌,發(fā)布后,內存占用依舊很高。

配置語法:

require('socket.io').listen(server, {perMessageDeflate: false});

客戶端發(fā)送的請求中含有這個字段:

首先這個參數是用來壓縮數據的,client 端默認是開啟,server 端是關閉的,出于某些原因,開啟后會導致內存和性能的消耗,官方建議是考慮后再決定是否開啟。但是低版本的 socket-io 是開啟的,比如 ^2.3.0 的版本(貌似是 bug,后續(xù)版本已經改為默認關閉)。

The extension is disabled by default on the server and enabled by default on the client. It adds a significant overhead in terms of performance and memory consumption so we suggest to enable it only if it is really needed.

https://github.com/socketio/socket.io/issues/3477#issuecomment-610265035

開啟后,內存仍舊居高不下。

console.log

另外一個現象就是現有的 Node 服務會打印一些日志,翻了一些網上的 NodeJs 內存泄漏的文章,有看到 console 日志輸出導致的泄漏的情況,因此注釋掉 console 之后繼續(xù)觀察內存占用,結果仍舊是內存高占用。

線索到這里似乎就斷掉了,沒有頭緒了。

日志

過了一天后,無意中看了一下日志文件,由于服務啟動的時候會打印一些啟動日志,發(fā)現有重復輸出的情況:

說明有重復運行的情況,為了驗證這一猜想,使用 top 命令查看。

TOP 命令

同時還想看一下具體的內存占用。發(fā)現居然有這么多的 worker process ,根據當前業(yè)務的實際使用情況不應該只有 2 ~ 4 個就夠了么,為什么要開這么多的子進程。

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                       
 90359 username       20   0  736m  38m  14m S  0.0  0.0   0:07.30 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90346 username       20   0  864m  38m  14m S  0.3  0.0   0:07.08 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90381 username       20   0  730m  38m  14m S  0.3  0.0   0:08.75 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90366 username       20   0  804m  37m  14m S  0.0  0.0   0:06.94 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90618 username       20   0  730m  37m  14m S  0.0  0.0   0:08.42 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90326 username       20   0  736m  37m  14m S  0.0  0.0   0:08.46 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90542 username       20   0  736m  37m  14m S  0.0  0.0   0:08.85 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90332 username       20   0  799m  37m  14m S  0.0  0.0   0:07.32 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90580 username       20   0  732m  37m  14m S  0.3  0.0   0:08.94 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90602 username       20   0  731m  37m  14m S  0.3  0.0   0:08.33 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90587 username       20   0  735m  37m  14m S  0.0  0.0   0:08.83 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90568 username       20   0  731m  37m  14m S  0.0  0.0   0:08.83 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90544 username       20   0  729m  37m  14m S  0.0  0.0   0:09.07 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90556 username       20   0  729m  37m  14m S  0.0  0.0   0:08.82 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90431 username       20   0  735m  37m  14m S  0.0  0.0   0:08.29 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90486 username       20   0  729m  37m  14m S  0.0  0.0   0:09.06 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90516 username       20   0  735m  37m  14m S  0.0  0.0   0:08.95 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90465 username       20   0  729m  37m  14m S  0.0  0.0   0:09.06 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90527 username       20   0  735m  37m  14m S  0.0  0.0   0:08.46 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90487 username       20   0  732m  37m  14m S  0.3  0.0   0:08.48 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90371 username       20   0  731m  37m  14m S  0.3  0.0   0:08.75 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90423 username       20   0  729m  36m  14m S  0.3  0.0   0:08.09 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90402 username       20   0  729m  36m  14m S  0.3  0.0   0:08.96 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90500 username       20   0  729m  36m  14m S  0.0  0.0   0:08.70 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90353 username       20   0  729m  36m  14m S  0.3  0.0   0:08.95 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90636 username       20   0  729m  36m  14m S  0.0  0.0   0:08.84 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90425 username       20   0  732m  36m  14m S  0.0  0.0   0:08.78 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90506 username       20   0  729m  36m  14m S  0.0  0.0   0:08.84 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90589 username       20   0  729m  36m  14m S  0.3  0.0   0:09.05 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90595 username       20   0  729m  36m  14m S  0.0  0.0   0:09.03 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90450 username       20   0  729m  36m  14m S  0.3  0.0   0:08.97 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90531 username       20   0  729m  36m  14m S  0.0  0.0   0:08.99 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90509 username       20   0  735m  36m  14m S  0.0  0.0   0:08.67 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90612 username       20   0  730m  36m  14m S  0.3  0.0   0:08.84 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90479 username       20   0  729m  36m  14m S  0.0  0.0   0:08.58 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90609 username       20   0  731m  36m  14m S  0.3  0.0   0:09.23 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90404 username       20   0  734m  36m  14m S  0.3  0.0   0:08.78 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90395 username       20   0  736m  36m  14m S  0.0  0.0   0:08.57 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90444 username       20   0  729m  36m  14m S  0.0  0.0   0:09.04 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90438 username       20   0  729m  36m  14m S  0.3  0.0   0:07.78 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90340 username       20   0  736m  36m  14m S  0.3  0.0   0:07.37 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90333 username       20   0  729m  36m  14m S  0.0  0.0   0:07.60 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90563 username       20   0  735m  36m  14m S  0.3  0.0   0:08.93 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90565 username       20   0  734m  36m  14m S  0.3  0.0   0:08.77 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90457 username       20   0  735m  36m  14m S  0.0  0.0   0:08.31 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90387 username       20   0  740m  36m  14m S  0.0  0.0   0:07.59 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90573 username       20   0  728m  35m  14m S  0.0  0.0   0:09.06 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90472 username       20   0  728m  35m  14m S  0.0  0.0   0:08.94 /usr/local/app/service_name/bin/src/index.js: worker process                                                      
 90313 username       20   0  588m  27m  13m S  0.0  0.0   0:00.46 /usr/local/app/service_name/bin/src/index.js: master process

由于 %MEM 這一列的數值在容器內部看不出具體的內存占用,都是顯示的 0.0,所以需要查看 VIRT, RES 和 SHR 這三個值,它們的含義可以在這里查看: https://www.orchome.com/298

我們更關心 RES,RES 的含義是指進程虛擬內存空間中已經映射到物理內存空間的那部分的大小,因此可以發(fā)現,一個 worker process 占用了 35 ~ 38M 之間的內存大小,一共有 48 個 worker process, 一個 master process。

48 個 worker process 是怎么來的呢?通過查詢 CPU 的邏輯個數,可以看到確實是 48 個。

# 總核數 = 物理CPU個數 X 每顆物理CPU的核數 
# 總邏輯CPU數 = 物理CPU個數 X 每顆物理CPU的核數 X 超線程數

# 查看物理CPU個數
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

# 查看每個物理CPU中core的個數(即核數)
cat /proc/cpuinfo| grep "cpu cores"| uniq

# 查看邏輯CPU的個數
cat /proc/cpuinfo| grep "processor"| wc -l

控制進程數

由于對 Taf 平臺不是很熟悉,了解到在 taf 上面運行 NodeJS 需要對應的 package: @tars/node-agent ,查了一下官網的使用文檔: https://tarscloud.github.io/TarsDocs/dev/tars.js/tars-node-agent.html

有一個 -i 的配置,代表 instances

-i, –instances

node-agent 采用 Node.js 原生的  Cluster 模塊來實現負載均衡。

可在此配置  node-agent 啟動的子進程(業(yè)務進程)數量:

未配置(或配置為  auto 、 0 ),啟動的子進程數量等于  CPU 物理核心 個數。

配置為  max ,啟動的子進程數量等于 CPU 個數(所有核心數)。

如果  node-agent 是由  tarsnode 啟動的,會自動讀取TARS配置文件中的  tars.application.client.asyncthread 配置節(jié)。

也可通過  TARS平臺 -> 編輯服務 -> 異步線程數 進行調整。

https://tarscloud.github.io/TarsDocs/dev/tars.js/tars-node-agent.html
通過這個 package 啟動 Taf 上的 NodeJs 服務,同時開啟負載均衡的能力,由于沒有配置具體的子進程(業(yè)務進程)數量,所以默認就是用了 CPU 物理核心 個數,因為是 2 個 cpu 所以再 *2,一共生成了 48 個 ‍♂️,每個 worker process 都要占用內存,所以內存占用一直居高不下。

可以在「私有模板」里修改配置:

然后重啟服務,查看內存占用:

可見 worker process 數量影響了內存占用,原先內存使用率的趨勢圖上會持續(xù)增長(剛開始也是因此懷疑內存泄漏),這個問題在降低了 worker process 后并沒有體現出來,目前暫且忽略,后續(xù)會持續(xù)觀察。

為了驗證重復 console 和 worker process 的關系,在開啟 2 個 worker process 的情況下,查看日志,確實是打印了 2 次。

總結

復盤一下這次的問題:

為什么沒有及時發(fā)現?

可能和前端開發(fā)者的角色有一定關系,對于后端服務的一些特性不太敏感。也沒有花精力去關注,或者說不知道,不了解。

是否可以提前避免?

可以有類似的告警機制提示 Node 服務的內存在上升趨勢,獲取我還沒有熟悉透 Taf 平臺的功能,后期摸索一下。

到此這篇關于NodeJs內存占用過高的排查的文章就介紹到這了,更多相關NodeJs內存占用過高內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用node.js 獲取客戶端信息代碼分享

    使用node.js 獲取客戶端信息代碼分享

    本文給大家分享一段使用node.js 獲取客戶端信息的代碼,非常的簡潔,推薦給大家。
    2014-11-11
  • 詳解用node編寫自己的cli工具

    詳解用node編寫自己的cli工具

    這篇文章主要介紹了詳解用node編寫自己的cli工具,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳解Puppeteer前端自動化測試實踐

    詳解Puppeteer前端自動化測試實踐

    這篇文章主要介紹了詳解Puppeteer前端自動化測試實踐,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • nodejs加密Crypto的實例代碼

    nodejs加密Crypto的實例代碼

    下面小編就為大家?guī)硪黄猲odejs加密Crypto的實例代碼。小編覺得挺不錯的, 現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • 使用Meteor配合Node.js編寫實時聊天應用的范例

    使用Meteor配合Node.js編寫實時聊天應用的范例

    這篇文章主要介紹了使用Meteor配合Node.js編寫實時聊天應用的范例,Node.js作為異步框架,其最突出的使用便是用來編寫實時應用程序,需要的朋友可以參考下
    2015-06-06
  • Node.js 使用流實現讀寫同步邊讀邊寫功能

    Node.js 使用流實現讀寫同步邊讀邊寫功能

    本文通過代碼給大家介紹了Node.js 使用流實現讀寫同步邊讀邊寫功能,非常不錯,具有參考借鑒價值,需要的額朋友參考下吧
    2017-09-09
  • 如何使用nexus3搭建npm私有倉庫

    如何使用nexus3搭建npm私有倉庫

    這篇文章主要介紹了如何使用nexus3搭建npm私有倉庫,包括安裝并運行私服的相關知識,本文結合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 在nodejs中創(chuàng)建child process的方法

    在nodejs中創(chuàng)建child process的方法

    這篇文章主要介紹了在nodejs中創(chuàng)建child process的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Koa2 之文件上傳下載的示例代碼

    Koa2 之文件上傳下載的示例代碼

    本篇文章主要介紹了Koa2 之文件上傳下載的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • NPM 安裝cordova時警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to

    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的相關資料,需要的朋友可以參考下
    2016-12-12

最新評論

政和县| 四子王旗| 元阳县| 青浦区| 翁牛特旗| 阿拉善盟| 永福县| 乌海市| 南溪县| 孝义市| 陆川县| 扎囊县| 邹平县| 宜州市| 绥化市| 宜春市| 平凉市| 康乐县| 霍山县| 祁阳县| 盐边县| 田阳县| 双牌县| 松滋市| 三明市| 霞浦县| 平乡县| 阿拉尔市| 阿尔山市| 红安县| 淮北市| 康保县| 石阡县| 章丘市| 图木舒克市| 汽车| 绵竹市| 绥宁县| 灵石县| 丰都县| 宿松县|