刚开始,先抛出一个问题:

你知道你们生产环境的 Node 服务平时占用内存多少吗?或者说是多少量级?

山月在面试 Node 候选人时,这个问题足够筛掉一半的自称Node精通者,不过没有回答上来,我往往会再补充一个问题,以免漏掉优秀的无线上经验的候选人:

如何知道某个进程消耗多少内存?

当使用 Node 在生产环境作为服务器语言时,并发量过大或者代码问题造成 OOM (out of memory) 或者 CPU 满载这些都是服务器中常见的问题,此时通过监控 CPU 及内存,再结合日志及 Release 就很容易发现问题。

本章将介绍如何监控本地环境及生产环境的内存变化

一个 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'))

进程内存监控

一些问题需要在本地及测试环境得到及时扼杀,来避免在生产环境造成更大的影响。那么了解在本地如何监控内存就至关重要。

pidstat 是 sysstat 系列 linux 性能调试工具的一个包,竟然用它来调试 linux 的性能问题,包括内存,网络,IO,CPU 等。

这不仅适用于 node,而且适用于一切进程,包括 python,java 以及 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 服务的 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

使用 htop 监控内存

生产环境内存监控

由于目前生产环境大都部署在 k8s,「因此生产环境对于某个应用的内存监控本质上是 k8s 对于某个 workload/deployment 的内存监控」,关于内存监控 metric 的数据流向大致如下:

k8s -> metric server -> prometheus -> grafana

架构图如下:

最终能够在 grafana 中收集到某一应用的内存监控实时图:

由于本部分设计内容过多,我将在以下的章节中进行介绍

这不仅仅适用于 node 服务,而且适用于一切 k8s 上的 workload

node获取服务器cpu信息,听说你不知道如何监控Node服务的内存?相关推荐

  1. 听说你不知道如何监控 Node 服务的内存?

    这是 「山月七八月原创计划」 中的「第一篇」文章,简述了如何监控 Node 服务的内存. 我将在接下来的时间完成 Node 系列及 GraphQL 系列的创作 刚开始,先抛出一个问题: ❝ 你知道你们 ...

  2. 批量获取服务器cpu信息,获取服务器的cpu利用率

    你得到的错误是什么? 这就是我正在使用同样的东西(剥离了一下).它显示每物理处理器的负载. strComputer = "." Dim arrProcessors : ReDim ...

  3. PHP 获取服务器详细信息

    PHP 获取系统信息,PHP 获取服务器详细信息 获取系统类型及版本号:    php_uname()                                   (例:Windows NT ...

  4. php 获取服务器,PHP 获取服务器详细信息

    获取系统类型及版本号:    php_uname()(例:Windows NT COMPUTER 5.1 build 2600) 只获取系统类型:          php_uname('s') (或 ...

  5. php获取服务器名称,PHP 获取服务器详细信息

    获取系统类型及版本号:    php_uname()     (例:Windows NT COMPUTER 5.1 build 2600) 只获取系统类型:          php_uname('s ...

  6. PHP 获取服务器详细信息【转】

    碰到此问题,做下记录 获取系统类型及版本号:    php_uname()                                   (例:Windows NT COMPUTER 5.1 b ...

  7. php如何获取服务器的信息,PHP获取当前服务器详细信息

    获取系统类型及版本号:          php_uname() (例:Windows NT COMPUTER 5.1 build 2600) 只获取系统类型:                     ...

  8. Node获取服务器信息

    在日常开发中,可能会遇到需要实时监控服务器运行信息,用来监控服务器运行情况,是否需要进行服务器的改配等操作.虽然服务器提供平台会有一系列监控数据,但是运营人员不可能频繁的登录控制台来查看服务器运行情况 ...

  9. linux服务器怎么查看cpu配置信息,linux服务器cpu信息查看详解

    在linux系统中,提供了/proc目录下文件,显示系统的软硬件信息.如果想了解系统中CPU的提供商和相关配置信息,则可以查/proc/cpuinfo.但是此文件输出项较多,不易理解.例如我们想获取, ...

最新文章

  1. Spring Cloud Alibaba基础教程:几种服务消费方式(RestTemplate、WebClient、Feign)
  2. oracle的后缀名,oracle表空间名字的后缀 :.ora和.dbf有什么不同?
  3. C++拷贝构造函数的陷阱
  4. windows下VS2015配置caffe
  5. Bootstrap实现弹出框和提示框效果代码
  6. 完全无人驾驶量产车Apollo Moon威马版首秀 成本降一半、能力翻10倍
  7. 只用一个marker 替换 高德_关于高德地图添加Marker遇到的一些坑
  8. vue 组件 全局组件和局部组件component
  9. 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)
  10. 分拆素数和(杭电2098)
  11. 数据库lib7第2, 3题(创建索引和触发器)
  12. linux 自学笔记
  13. Linux下学习进程控制
  14. 【Qt】用setValue()设置UI控件内的内容,如何避免valuechange()被触发
  15. 全景图(三):在Unity3D上实现360°球面投影
  16. 新云人才招聘系统抖音小程序申请配置教程
  17. 好书推荐之《不能承受的生命之轻》 隐私策略(Privacy policy)
  18. 穷举php,[讨论]穷举攻击
  19. linux ping结果中mdev,ping之mdev值
  20. Chrome将已有的插件,打包成crx供其他电脑使用

热门文章

  1. 从通用分页存储过程[ROWCOUNT方式]抽出适合自己需求的分页过程
  2. Spring常用注解的讲解
  3. C++学习——c语言和C++语言中的struct
  4. linux标准I/O——按字符输入和输出
  5. linux的常用操作——read函数和write函数
  6. 库存商品表html源码,JSP+Servlet+数据库的方式完成一个简易的库存商品管理系统...
  7. php代码怎么修改成laravel,Laravel框架实现即点即改功能的方法分析
  8. 牛客网数据开发题库_牛客网SQL题库NO.32~40
  9. sqlite查询乘以某列如果是null就换成_大数据之Hive group by with cube/rollup分组查询...
  10. java语言计算器怎么写_求助,一个计算器的括号功能怎么写啊。