NodeJs性能分析工具

(头等人,有本事,没脾气;二等人,有本事,有脾气;末等人,没本事,大脾气。——南怀瑾)

在这里插入图片描述

NodeJs内存分析的必要性

回顾过去,我们排查web应用问题的途径通常是一下几种

  • 有显式异常的情况下(比如前端报错或者后端接口异常等),可以直接定位前端模块,确认不是前端的问题,则再排查对应的后端接口并根据异常的提示直接查找对应代码。这种问题的定位和排查速度最快最简单。该类问题通常是发版前的代码测试不完全导致,也是日常线上问题的主要排查途径
  • 没有显式异常,用户前端部分页面出现性能问题,比如加载时间长,后端接口请求时间长等。通常这类问题是在产品某个版本发布后造成,确认不是前端的问题,则将部分超时的接口发给后端,后端先可以快速定位到这几个接口,排查代码问题。该类问题通常在测试阶段很难发现,也是常见的线上类问题
  • 没有显式异常,用户也没有反馈问题,但后端服务得内存持续上升,无法定位到具体的接口,查看最近发版的代码也没有问题,那么该问题就是典型的内存泄漏,需要借助专业的工具和可视化来解决

针对第三种情况,我们无法快速的定位到问题代码,但可以借助排查工具,head-dump和chrom的memory等一起分析内存使用情况,排查内存空间占用大的对象,再利用该对象定位业务代码进行排查

head-dump

包管理地址
将v8内存数据转存为一个快照数据进行分析

模拟数据泄漏代码

模拟一个后端服务内存泄漏场景,初始化全局变量customGlobalList,每次访问接口都向该数组添加100w个数字,随着接口访问频次的增加,该数组的容量也随之增加,从而造成内存泄漏的问题

import {
    
     Injectable } from "@nestjs/common";

const customGlobalList = [];

@Injectable()
export class AppService {
    
    

  constructor(
  ) {
    
     }

  getNestCli () {
    
    
    for (let index = 0; index < 1000000; index++) {
    
    
      customGlobalList.push(index);
    }
  }
}

添加内存快照打印代码

通过接口或者定时器触发,为了简单起见,我在这里通过接口触发

import {
    
     Injectable } from "@nestjs/common";
import * as heapdump from "heapdump";

const customGlobalList = [];

@Injectable()
export class AppService {
    
    

  constructor(
  ) {
    
     }

  getNestCli () {
    
    
    for (let index = 0; index < 1000000; index++) {
    
    
      customGlobalList.push(index);
    }
  }
  getHead () {
    
    
    console.log('fileName', `${
      
      __dirname}/${
      
      new Date().valueOf()}.heapsnapshot`);
    const fileName = `${
      
      __dirname}/${
      
      new Date().valueOf()}.heapsnapshot`;
    heapdump.writeSnapshot(fileName);
  }
}

通过chrom memory进行分析

我们分别打印两次快照,一次是服务刚启动时打印,一次是访问多次内存泄漏接口时打印

加载内存快照

打开chrom控制台,选择memory。左侧是已经加载好的内存快照,其中192mb的是有内存泄漏问题的,13.4m的是服务刚启动时的快照。
在这里插入图片描述
在这里插入图片描述

快照分析类型

Summary

按照对象列表排列,可以根据排序快速定位占用内存大的对象。

Shallow Size

对象自身占用的内存大小

Retained Size

对象被回收后可释放的内存大小

在这里插入图片描述
通过队Retained Size排序,我们发现array数组中的对象占据了94%的内存空间,
在这里插入图片描述
我们展开数组列表,查看下方的对象信息,就能够找到customGlobalList了

Comparison

通过对比两个快照来快速获悉以下信息

  • New - Comparison 特有 - 新增项
  • Deleted - Comparison 特有 - 删除项
  • Delta - Comparison 特有 - 增量
  • Alloc. Size - Comparison 特有 - 内存分配大小
  • Freed Size - Comparison 特有 - 释放大小
  • Size Delta - Comparison 特有 - 内存增量

在这里插入图片描述

Containment

查看内存内容。更适合查看对象结构,有助于分析对象的引用情况。适用于分析闭包以及深入分析对象
在这里插入图片描述

Statistics

统计视图,快速获悉各数据结构的内存占比
在这里插入图片描述

easy-monitor

包管理地址
nodejs社区说明
轻量级的 Node.js 项目内核性能监控 + 分析工具,通过可视化界面,快速获悉服务cpu和内存的性能问题。其原理也是类似headdump,只不过在上层做了界面可视化以及更智能的分析方案

快速集成

安装
npm install easy-monitor
引入和启动
import * as easyMonitor from "easy-monitor";
easyMonitor('nestjs');
访问

在这里插入图片描述

验证

在这里继续调用我们之前编写的内存泄漏代码接口,然后点击easy-monitor的memory和start开始监测

在这里插入图片描述

xprofiler

npm仓库地址
github仓储地址
在线体验地址
Easy-Monitor v3.0 Node.js Runtime 插件,输出性能日志,并且可以进行实时的运行时状态采样

ali-node

阿里文档地址
云栖社区 Node.js 性能平台官方博客
知乎 Egg.js 团队 Node.js 专栏
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42427109/article/details/130953329