首頁  >  文章  >  web前端  >  Node服務中如何監控本地環境及生產環境的記憶體變化?

Node服務中如何監控本地環境及生產環境的記憶體變化?

青灯夜游
青灯夜游轉載
2020-08-28 10:21:522266瀏覽

Node服務中如何監控本地環境及生產環境的記憶體變化?

當使用Node 在生產環境作為伺服器語言時,並發量過大或程式碼問題造成OOM (out of memory) 或CPU 滿載這些都是伺服器常見的問題,此時透過監控CPU 及內存,再結合日誌及Release 就很容易發現問題。

【影片教學推薦:node js教學 】

本章將介紹如何監控本地環境及生產環境的記憶體變化

一個Node 應用實例

所以,如何動態監控一個Node 程序的記憶體變化呢?

以下是一個 Node Server 的範例,並且是一個有記憶體洩漏問題的範例,並且是山月在生產環境定位了很久的問題的精簡版。

那次記憶體洩漏問題中,導致單一容器中的記憶體從原先的 400M 暴漲到 700M,在 800M 的容器資源限制下偶爾會發生 OOM,導致重啟。一時沒有定位到問題 (發現問題過遲,半個月前的時序資料已被吞沒,於是未定位到 Release),於是把資源限制上調到 1000M。後來發現是由ctx.request 掛載了資料庫某個大字段而致
const Koa = require('koa')
const app = new Koa()

function getData () {
  return Array.from(Array(1000)).map(x => 10086)
}

app.use(async (ctx, next) => {
  ctx.data = getData()
  await next()
})

app.use(ctx => {
  ctx.body = 'hello, world'
})

app.listen(3200, () => console.log('Port: 3200'))

#進程記憶體監控

一些問題需要在本地及測試環境及時扼殺,來避免在生產環境造成更大的影響。那麼了解在本地如何監控記憶體就至關重要。

pidstatsysstat 系列 linux 性能調試工具的一個包,竟然用它來調試 linux 的性能問題,包括內存,網絡,IO,CPU 等。

這不僅試用與node,也適用於一切進程,包括pythonjava 以及go

# -r: 指输出内存指标
# -p: 指定 pid
# 1: 每一秒输出一次
# 100: 输出100次
$ pidstat -r -p pid 1 100

而在使用pidstat 之前,需要先找到進程的pid

如何找到Node 進程的pid

node 中可以透過process.pid 來找到進程的pid

> process.pid
16425

雖然透過寫程式碼可以找到pid,但是具有侵入性,不太實用。那如何透過非侵入的手段找到 pid 呢?有兩種辦法

  1. 透過多餘的參數結合ps 定位進程
  2. 透過連接埠號結合lsof 定位進程
$ node index.js shanyue

# 第一种方法:通过多余的参数快速定位 pid
$ ps -ef | grep shanyue
root     31796 23839  1 16:38 pts/5    00:00:00 node index.js shanyue

# 第二种方法:通过端口号定位 pid
lsof -i:3200
COMMAND   PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
node    31796 root   20u  IPv6 235987334      0t0  TCP *:tick-port (LISTEN)

使用pidstat 監控記憶體

Node服務中如何監控本地環境及生產環境的記憶體變化?

從上述程式碼可以知道,node 服務的pid 為31796 ,為了可以觀察到記憶體的動態變化,再施加一個壓力測試

$ ab -c 10000 -n 1000000 http://localhost:3200/
# -r: 指输出内存指标
# -p: 指定 pid
# 1: 每一秒输出一次
# 100: 输出100次
$ pidstat -r -p 31796 1 100
Linux 3.10.0-957.21.3.el7.x86_64 (shuifeng)     2020年07月02日  _x86_64_        (2 CPU)

             UID       PID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command
19时20分39秒     0     11401      0.00      0.00  566768  19800   0.12  node
19时20分40秒     0     11401      0.00      0.00  566768  19800   0.12  node
19时20分41秒     0     11401   9667.00      0.00  579024  37792   0.23  node
19时20分42秒     0     11401  11311.00      0.00  600716  59988   0.37  node
19时20分43秒     0     11401   5417.82      0.00  611420  70900   0.44  node
19时20分44秒     0     11401   3901.00      0.00  627292  85928   0.53  node
19时20分45秒     0     11401   1560.00      0.00  621660  81208   0.50  node
19时20分46秒     0     11401   2390.00      0.00  623964  83696   0.51  node
19时20分47秒     0     11401   1764.00      0.00  625500  85204   0.52  node

對於輸出指標的意義如下

  • RSS: Resident Set Size,常駐記憶體集,可理解為內存,這就是我們需要監控的記憶體指標
  • VSZ: virtual size,虛擬記憶體

從輸出可以看出,當施加了壓力測試後,記憶體由19M 漲到了85M。

使用top 監控記憶體

pidstat 是屬於sysstat 下的linux 效能工具,但在mac 中,如何定位記憶體的變化?

此時可以使用top/htop

$ htop -p 31796

Node服務中如何監控本地環境及生產環境的記憶體變化?

#生產環境記憶體監控

由於目前生產環境大都部署在k8s因此生產環境對於某個應用的記憶體監控本質上是k8s 對於某個workload/deployment 的記憶體監控,關於記憶體監控metric 的資料流向大致如下:

k8s -> metric server -> prometheus -> grafana

架構圖如下:

Node服務中如何監控本地環境及生產環境的記憶體變化?

Node服務中如何監控本地環境及生產環境的記憶體變化?

#以上圖片取自以下文章

#最終能夠在grafana 中收集到某一應用程式的記憶體監控即時圖:

由於本部分設計內容過多,我將在以下的章節中進行介紹

這不僅適用於node 服務,而且適用於一切k8s 上的workload

總結

本章介紹了關於Node 服務的內部存在本地環境及生產環境的監控

1、本機使用htop/toppidstat 監控進程記憶體

2、生產環境使用k8s/metric-server/prometheus/grafana 監控node 整個應用程式的記憶體

當監控到某一服務發生記憶體洩漏後,如何解決問題?因此接下來的文章將會講到

1、生產環境是如何監控整個應用的記憶體的

2、當生產環境發生OOM 後,如何快速定位

3、真實生產環境若干OOM 的範例定位

更多程式相關知識,可至:程式設計入門! !

以上是Node服務中如何監控本地環境及生產環境的記憶體變化?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除