15

啰嗦

alinode是基本上是免费开源的,不只是可以运行在ECS里面,理论上可以应用在任何地方(只要面子上过得去)。本文将赘述一下alinode的使用方法。

本文首先啰嗦一下 Node.js 平台的性能问题分析所包含的一些内容,第二part再叙述下 alinode 是如何使用的

性能问题分析

要定位 Node.js 的性能问题,一般要对Node进程进行性能方面的进程分析。

进程分析一般包括 内存、CPU、EventLoop、ActiveHandlers 等的分析。对于开发人员来说,这里面包括3个主要任务:

  • 第一,压测应用。通常我们希望分析的都是应用在实际生产运行时的一个状况,而这个状况可以通过自己压测来模拟。
  • 第二,获取数据。也就是获取到我们的 CPU状况、内存状况等信息。这个一般通过运行时或运行时的底层提供的一些API来获取。例如Node的语言执行引擎V8就提供了cpu profile的能力。
  • 第三,分析数据。拿到数据后,我们需要对数据进行分析以让我们快速定位到问题。一般拿到的数据可读性比较差,因此这一步通常是对数据可视化,例如cpu profile可以通过工具转换为火焰图。或者通过其他第三方工具如v8-analysis工具库提供分析。

压测应用

这个有几个比较常用的工具,例如 Apache ab、wrk 以及 Node.js 编写的 autocannon

这里就不具体讲用法了,通过压测工具,我们可以量化我们站点的性能指标,在性能问题排查过程中为我们提供依据。

一般我们的性能指标需要达到一定的吞吐量 req/sec,且单个请求的耗时要在预期范围之内。否则耗时过高影响用户体验、吞吐太低则会造成某些用户访问失败。

数据获取

CPU

cpu一般要观察一些时间来拿到他的函数执行堆栈情况,比如 alinode 进行dump时也是要等3分钟。

  • 方法1:直接使用v8底层对Node暴露的api。我们只需在启动node应用的时候,传入
        node --prof app.js

node.js 从 4.4.0 版本开始内置了 profiler, --prof 命令选项运行应用会在当前目录生成性能日志文件


以上命令会在项目根目录会生成 `isolate-xxxxxxx-v8.log` 格式的文件,这个log文件还不能直接进行分析,一般可视化工具都是要一个json文件。因此,log需要进行预处理,我们可以这样预处理这个log:
node --prof-process --preprocess isolate-xxxxxxxxxx-v8.log > v8.json

这样就可以把它转为一个json字符串文件。

  • 方法2:使用npm包 v8-profile

    使用示例如下:

    profiler.startProfiling('', true); 
    setTimeout(function() { 
      var profile = profiler.stopProfiling('');
        profile.export()    
        .pipe(fs.createWriteStream(`cpuprofile-${Date.now()}.cpuprofile`)) 
        .on('finish', () => profile.delete()) 
    }, 1000);

内存

  • 方法1: heapdump 这个模块可以用来进行内存数据的采集。这个包需要侵入代码,在代码中引用后,可以通过其API进行dump。或者在外部给进程发送 kill -USR2 <pid> 的信号。
  • 方法2:v8-profile。这也是一个需要侵入node代码的模块,通过该模块可以获取 heapdump 和 cpu profile

数据分析

分析的话,无非是用一些易于查看的数据展示工具或定位工具来帮助我们更好的展示数据。比如能按函数热度去展示cpu profile文件。

  • 方法1: 使用v8自身提供的界面分析工具。

    git clone https://github.com/v8/v8.git

    打开 v8/tools/profview/index.html 文件,是个静态界面,在界面中心选择刚生成的 v8.json文件,文件解析成功后,界面上就展示了函数调用的时间信息了。

  • 方法2: 使用 chromedevTools
    具体参考:Node性能问题排查指南

    这里不再赘述了。chromedevtool提供了heavvvy、chart多种视图,还是很不错的。

  • 方法3:使用 v8-analysis工具

    v8-analysis这个模块可以解析 v8-profilerheapdump 等工具输出的cpu & heap-memory日志,可以提供:

    • v8引擎逆优化或者优化失败的函数标红展示以及优化失败原因展示
    • 函数执行时长超过预期标红展示
    • 当前项目中可疑的内存泄漏点展示
  • 方法4:
    对于cpu profile,还可以自己动手制作火焰图(这就有点考验动手能力了)。 用FlameGraph这个工具。

alinode使用

通过上面简单的介绍,可以发现性能分析这里有2个痛点。一个是收集数据,需要侵入代码,手工执行相应的指令。另外一个是: 分析工具五花八门,哪怕用chrome devtool也得经历把dump的数据下载回来导入的比较痛苦的过程。

alinode 阿里Node.js性能平台 对以上一些问题的解决过程进行了集成,提供了更易用的体验,解决了大部分的痛点。而且是免费开源的(基本上)。alinode通过 错误日志、操作系统指标(cpu/内存/磁盘/IO)、慢日志、异常等维度来监控node应用,并提供了如 coredump、cpuProfile、heamdump 等工具,同时提供了Profile的在线web数据可视化分析的能力.

总体来看,alinode的几个工具也就是提供了本文最开始提到的性能分析相关的能力,即数据提取、数据分析能力(当然还有额外的监控通知、好看的UI、实时数据展示)。

总体架构

alinode的设计架构如下:
架构图

其实,只看技术细节部分的话。alinode包括这3部分的组件,我们从底向上说:

  1. alinode改造后的Node 运行时。 这个node基本上是原生node,只是阿里在里面给加入了dump数据的开关,从而可以远程收集性能数据。alinode版本与原生版本的对应关系可以戳这里。(大家伙自己使用时也无须关心有什么后门,因为只是加了一些性能分析能力,且开源正在路上)
  2. agenthub。这是一个安装在应用服务器上的一个agent。它负责与云端alinode服务进行通信。云端管理系统进行命令下发、机器进行数据上报 都要通过这个agent来执行。因此,它是node进程与云端管理平台的桥梁。
  3. alinode云服务。其实就是一个管理平台了。云端会有相应的服务来与机器上的agenthub建立websocket通信,用于下发命令或收集信息。你可以在云端管理平台上通过web界面集中式的处理性能分析的所有任务。

使用步骤

我在本机macbook上进行了站点的性能分析,下面我们来看看 alinode 使用的基本步骤,对我们学习别人的设计和思路也是很有帮助的。除了观看这里的步骤之外,你还可以参考官方帮助文档 作为辅助。

从上面的分析可以看到,我们在本机要做的事情其实就是安装阿里改装后的node运行时(alinode)以及agenthub。下面是具体步骤:

  • 安装tnvm。我们知道nvm是一个node版本管理器,淘宝这里出了一个tnvm,用来管理anlinode版本。所以我们先安装tnvm,之后再通过tnvm来安装alinode。
wget -O- https://raw.githubusercontent.com/aliyun-node/tnvm/master/install.sh | bash

执行安装脚本后,我们再执行

source ~/.bash_profile ,# 你的可能是 ~/.bash_rc    

此时tnvm安装成功。

  • 安装alinode

执行tvnm命令查看下 alinode远程有哪些版本

tnvm ls-remote alinode

选择一个alinode版本进行安装

tnvm install alinode-vx.y.z   # 4.8.0->10.16.0

比如我安装的 v4.8.0,他对应 node的 v10.16.0

tnvm install alinode-v4.8.0 

接下来,别忘了要 use 一下你安装的版本。

tnvm use alinode-v4.8.0  #别忘这一句。

此时,执行 which node 命令你会发现已经使用上了 tnvm管理的alinode:

/Users/cuiyongjian/.tnvm/versions/alinode/v4.8.0/bin/node
  • agenthub安装

agenthub 只是一个 npm 命令行工具,通过如下命令可以很简单的完成安装:

npm install @alicloud/agenthub -g

agenthub接收和发送信息,需要知道云上的服务ID. 所以他启动需要一份配置,我们在任意地方新建一个config.json

  1 {
  2  "appid": "80535",
  3  "secret": "3c4d************5”, // 你在aliyun上新建node监控实例时,会给你一个appid和secret
  4  "logdir": "/tmp"      
  5 }

然后启动agenthub:

DEBUG=* agenthub start config.json

注意点:这里的 /tmp是指的agenthub从哪个目录来获取dump出来的日志文件。 因此这个目录必须跟你接下来启动node应用时指定的日志输出目录一致,否则你的agenthub将无法上传dump信息。

  • 运行 node 应用进程

我们来启动我们的应用:

NODE_LOG_DIR=/tmp ENABLE_NODE_LOG=YES node app.js
NODE_LOG_DIR=/tmp ENABLE_NODE_LOG=YES pm2 start app.js

例如我的实际项目:

sudo NODE_LOG_DIR=/tmp ENABLE_NODE_LOG=YES PORT=80 MODE=ssr NODE_ENV=production CGI_ENV=online node ./backend/app.js

这俩LOG的环境变量必须指定。一个是前文所说的日志输出目录,一个是是否打开日志功能,如果不这样配置肯定就不能进行远程dump了

  • 一些小问题

    • egg.js 项目
      如果你是egg的项目,那就不用亲自启动agenthub了。egg集成的话已经把agent内置在插件里了,所以直接用插件就好了。这里不再赘述可以看文档
    • 安装 alinode 运行时之后,别忘记 tnvm use;另外有时候你新开一个terminal的话,你的PATH环境变量会被还原。此时可以再次执行 source ~/.bash_profile 来让tnvm的node路径优先。
    • 当你在管理平台查看数据或执行dump命令时,可能会提示出错。这里有几点排查思路:

      1. agenthub要与阿里云管理平台建立连接,而我们的公司网络不用代理的情况下无法联通。这里你可以想办法改agenthub的代理。我这里采用了最简单的办法,直接使用 staffWifi。。
      2. 可以tail -f ~/.agenthub.log 来看看本机agent日志。比如日志里会看到你网络连接有问题或日志目录配错了;启动应用时别忘了那两个LOG的环境变量。

clipboard.png

云管理界面

打开 node.console.aliyun.com ,进入管理控制台首页。

  • 首先看到的是:

控制台首页

这里会展示实例。所谓实例就是你的一台机器。在这里可以点击主页进入一个实例,也可以配置该实例相关的告警(如针对错误日志、内存等阈值配置告警),还可以配置团队成员。

  • 点开实例主页,我们可以看到系统整体资源状况的仪表盘:

仪表盘

左侧链接可以看到:针对当前实例有这么几个功能: 进程信息查看和管理、系统信息、异常信息、慢日志信息、依赖信息。

  • 点击进程选项,我们就可以找到我们进程信息。我们在界面右上角的“正在运行的进程” 中选中我们要分析的node进程,就可以对他进行各种dump数据和分析操作了。例如我们选中node进程,可以查看他的qps、cpu使用率等基本信息:

进程面板

  • 点开进程面板右下角的 “数据趋势” 按钮,还可以按时间线来看各项指标的变化曲线,便于发现问题。

数据变化趋势

  • 系统监控数据面板可以看到机器整体性能:

系统监控

  • 慢日志面板会按照请求的耗时情况给到超出预期的耗时,耗时从高到低排序展示在面板上,让你知道系统的最慢耗时情况。这里没有截图。
  • 进程面板右下角的“抓取性能数据”就是我们分析性能的利器了。这里有 heapDump,cpu profile, 堆时间线(可以看堆变化情况),gctrace, 诊断报告。更多详情可以参考文档

dump之后就去点页面左侧 文件列表 菜单, 来到文件面板这里,查看文件生生进度,生成完成之后就点击转储,转储完成就课可以点击分析。

文件列表

  • 在线分析

当我们点击一个已经转储完成的 CPU profile 文件,管理平台会打开一个新页面展示火焰图:

火焰图

cpuprofile还可以直接点击 devtool分析 查看,这种分析会自动会在浏览器中打开一个chrome风格 分析工具。很神奇:

devtool分析

GcTrace分析:

 GCtrace 分析

一些资料

你不知道的Node.js性能优化,读了之后水平直线上升

对node工程进行压力测试与性能分析

阿里云的Node.js 应用故障排查手册

alinode ppt: alinode-基于Node.js运行时的应用性能管理解决方案

你不知道的Node.js性能优化


sheldon
947 声望1.6k 粉丝

echo sheldoncui