怎么獲取Node性能監控指標?獲取方法分享( 二 )

CPU 負載CPU的負載(loadavg)很好理解 , 指某段時間內占用 CPU 時間的進程和等待 CPU 時間的進程數為平均負載(load average) , 這里等待CPU 時間的進程是指等待被喚醒的進程 , 不包括處于wait狀態進程 。
在此之前我們需要學習一個node的API
os.loadavg()返回包含 1、5 和 15 分鐘平均負載的數組 。
平均負載是操作系統計算的系統活動量度 , 并表示為小數 。
平均負載是 Unix 特有的概念 。 在 Windows 上 , 返回值始終為 [0, 0, 0]
它用來描述操作系統當前的繁忙程度 , 可以簡單地理解為CPU在單位時間內正在使用和等待使用CPU的平均任務數 。 CPU load過高 , 說明進程數量過多 , 在Node中可能體現在用紫禁城模塊反復啟動新的進程 。
const os = require('os');// CPU線程數const length = os.cpus().length;// 單核CPU的平均負載 , 返回一個包含 1、5、15 分鐘平均負載的數組os.loadavg().map(load => load / length);內存指標我們先解釋一個API , 要么你看不懂我們獲取內存指標的代碼
process.memoryUsage():該函數返回4個參數 , 含義及差別如下:

    rss: (Resident Set Size)操作系統分配給進程的總的內存大小 。 包括所有 C++ 和 JavaScript 對象和代碼 。 (比如 , 堆棧和代碼段)heapTotal:堆的總大小 , 包括3個部分 ,
      已分配的內存 , 用于對象的創建和存儲 , 對應于heapUsed未分配的但可用于分配的內存未分配的但不能分配的內存 , 例如在垃圾收集(GC)之前對象之間的內存碎片
    heapUsed: 已分配的內存 , 即堆中所有對象的總大小 , 是heapTotal的子集 。 external: 進程使用到的系統鏈接庫所占用的內存 , 比如buffer就是屬于external里的數據 。 buffer數據不同于其他對象 , 它不經過V8的內存分配機制 , 所以也不會有堆內存大小限制 。
用如下代碼 , 打印一個子進程的內存使用情況 , 可以看出rss大致等于top命令的RES 。 另外 , 主進程的內存只有33M比子進程的內存還小 , 可見它們的內存占用情況是獨立統計的 。
var showMem = function(){ var mem = process.memoryUsage(); var format = function(bytes){ return (bytes / 1024 / 1024).toFixed(2) + ' MB'; }; console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss) + ' external:' + format(mem.external)); console.log('-----------------------------------------------------------');};對于Node而言 , 一旦出現內存泄漏 , 不是那么容易排查 。 如果監控到內存只升不降 , 那么鐵定存在內存泄露問題 。 健康的內存使用應該有升有降 。 訪問大的時候上升 , 訪問回落下降
獲取內存指標的代碼const os = require('os');// 查看當前 Node 進程內存使用情況const { rss, heapUsed, heapTotal } = process.memoryUsage();// 獲取系統空閑內存const systemFree = os.freemem();// 獲取系統總內存const systemTotal = os.totalmem();module.exports = { memory: () => { return { system: 1 - systemFree / systemTotal, // 系統內存占用率 heap: heapUsed / headTotal, // 當前 Node 進程內存占用率 node: rss / systemTotal, // 當前 Node 進程內存占用系統內存的比例 } }}磁盤空間指標磁盤監控主要是監控磁盤的用量 。 由于日志頻繁寫的緣故 , 磁盤空間被漸漸用光 。 一旦磁盤不夠用 , 將會引發系統的各種問題 。 給磁盤的使用量設置一個上限 , 一旦磁盤用量超過警戒值 , 服務器的管理者就應該整理日志或者清理磁盤 。
以下代碼參考easy monitor3.0
    先用df -P獲得所有磁盤情況 , 這個-P是為了防止有換行startsWith('/')保證是真實磁盤 , 不是虛擬的line.match(/(\d+)%\s+(/.*$)/) => 匹配磁盤情況和掛載的磁盤 , 比如'1% /System/Volumes/Preboot'match[1]是字符串 , 表示使用率 , match[2]表示掛載的磁盤名稱
const { execSync } = require('child_process');const result = execSync('df -P', { encoding: 'utf8'})const lines = result.split('\n');const metric = {};lines.forEach(line => { if (line.startsWith('/')) { const match = line.match(/(\d+)%\s+(\/.*$)/); if (match) { const rate = parseInt(match[1] || 0); const mounted = match[2]; if (!mounted.startsWith('/Volumes/') && !mounted.startsWith('/private/')) { metric[mounted] = rate; } } }});console.log(metric)I/O指標I/O負載指的主要是磁盤I/O 。 反應的是磁盤上的讀寫情況 , 對于Node編寫的應用 , 主要是面向網絡服務 , 是不太可能出現I/O負載過高的情況 , 多讀書的I/O的壓力來源于數據庫 。

推薦閱讀