《深入浅出Node.js》作者分享:Node.js应用性能监控与问题诊断

直播回顾视频:

以下内容是根据直播和PPT整理。



Node.js的优势与劣势

Node.js是基于JavaScript编写而成的强大的Web开发框架,它易于上手、入门简单;同时ECMAScript新规范、特性更新活跃,按年为单位进行更新。得益于弱类型语言的特性,Node.js的开发效率奇高,通过使用事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js特别适合于web应用或API服务器,例如手机上的APP,如果它的服务器端采用Node.js来搭建,整体的开发效率会提高很多倍;此外,Node.js的开发者社区相当活跃(参考NPM:https://www.npmjs.com/和CNPM:https://npm.taobao.org/),目前由专门的基金会稳定维护。

由于Node.js是一个运行于服务端的基于Chrome V8引擎的 JavaScript 运行环境,而V8最初是用于浏览器(Short running)场景设计的,对服务端并不友好,其中最为重要的一点是缺乏对大堆应用的良好支持;同时,Node.js的从业者部分来自前端,对服务器领域(CPU/Memory/IO/Disk)缺乏了解,缺乏对运行时环境底层细节的了解(V8/Libuv);此外,Node.js相比于Java/C++等语言仍属于新兴技术,它的配套的Profiling工具并不成熟,对生产环境不友好,例如CPU百分比飙高,QPS上不去;内存持续增长,无法回收,内存泄露以及GC频繁产生等问题。

为了解决上述问题,Node.js推出了一些常见的性能优调优方案:

  •  系统工具:常见的系统调优工具有Dtrace、perf、ps、sar、top、lsof,这些工具只能从外围观察应用的运行状态;
  •  专属工具:最常见的专属工具是Devtools,其作为Web前端开发性能调试的必备工具,可以用于CPU profiling、Heap Snapshot、Head Allocations;
  •  APM工具:常见的APM工具包括New Relic、oneapm、tingyun。该类工具针对多种语言,为每一种语言编写探针,能够获取到通用性的性能监控数据,但对内核无能为力;能够发现问题,但不能解决问题。

以上三种常见的性能调优方案各有优缺点,随着Node.js应用逐步推广,涌现了一批新生代应用性能管理方案:

  •  StrongLoop by IBM
  •  NLSolid by NodeSoure
  •  Alinode by Aliyun

下面来具体讲解alinode。

什么是alinode?

alinode是阿里云出品的应用性能管理解决方案,是一套基于社区 Node 改进的运行时环境和服务平台,它具有以下特点:

  •  无需任何代码改动,对业务代码无任何侵入性;
  •  由全兼容官方Node的运行时提供能力;
  •  通过在线开关功能,随时获取内核性能状态;
  •  借助离线分析能力,精准分析问题节点。

整体来看,alinode在社区的基础上内建了强大的支持功能,帮助开发者迅速洞见性能细节,快速定位疑难杂症,直探问题根源。

alinode应用解决方案的架构

alinode应用解决方案的架构图如上所示,整套服务由 alinode运行时、AgentX、命令集、服务平台四个部分组成。线上运行在与社区版Node.js兼容的alinode运行时上,也就是开发者写好的代码运行在alinode运行时上,该运行时配合部署的开源Agentx,可以定时创建数据、截取快照并上传应用状态到alinode云服务平台上。

线下可以使用alinode或社区版Node.js开发,数据上传到alinode云服务平台之后;利用alinode提供的可视化分析工具监控与调优,当出现异常时,可发送报警给相关人员。

如何部署alinode?

使用alinode解决方案之前,需要在服务器上部署 AgentX、Alinode 运行时和一组命令集。为了便于部署,alinode除了自助式部署外,还提供了交互式部署和从镜像部署两种方式。当想了解每一步详细的细节时,请使用自助式部署;当想轻松部署时,请使用交互式部署;当还没有 ECS 实例时,可以使用镜像来部署,alinode镜像里已经部署好了相关软件,仅需输入 appid 和 secret 配置即可。

下面来具体讲解自助完成alinode服务的安装。

第一步:注册应用。

用户可通过http://alinode.aliyun.com/,登录到alinode官网,然后进入控制台,进行应用创建。

第二步:安装tnvm(安装 alinode 运行时)。

alinode是与 Node 社区版完全兼容的二进制运行时环境,推荐使用tnvm工具进行安装,它能自动识别操作系统和系统架构。其安装指令如下:

wget -O- https://raw.githubusercontent.com/aliyun-node/tnvm/master/install.sh | bash

完成安装后,您需要将tnvm添加为命令行程序。根据平台的不同,可能是~/.bashrc,~/.profile或~/.zshrc等,请根据提示进行手工操作。如:

source ~/.bashrc

完成上述操作后,tnvm就成为当前 shell 环境中的命令了。执行 tnvm ls-remote alinode查看所有的 alinode 版本。

执行下面的命令安装一个版本:

tnvm install alinode-vx.y.z

执行下面的命令使用一个版本:

tnvm use alinode-vx.y.z

tnvm是一个覆盖nvm所有功能的命令功能,你也可以通过它来安装 Node 官方的版本。更多操作请参考 tnvm 的文档。完成 alinode 的安装后,可以通过node -p 'process.alinode'来查看是否为 alinode 的版本。确认无误后就可以使用任何启动普通 node 应用的方式来启动 alinode 应用了。需要注意的一点是:Alinode二进制文件仅支持LTS版本。

第三步:安装Commands。

Commands(命令集)为一组 Alinode 服务执行任务所需要的命令集合,Alinode 服务有且仅有执行这些命令的权限。

命令集位于:https://github.com/aliyun-node/commands,使用者可以通过clone,或者直接下载压缩包的方式将命令集安装到服务器上的某个路径下即可。

第四步:部署AgentX。

AgentX 是为 alinode 服务而研发的常驻代理服务,可以帮助执行一些监控和诊断的操作。它同时是一个 npm 命令行工具,通过如下命令可以完成安装:

npm install agentx -g

安装完成后,会存在一个叫做agentx的命令。此处也推荐阿里云上的 Node 用户使用 cnpm 来安装任何模块。

配置和运行 AgentX

AgentX 使用一个 JSON 格式的文件作为配置项。

{
  "server": "120.55.151.247:8080",
  "appid": "您的应用ID",
  "secret": "您的应用Secret",
  "heartbeatInterval": 60,
  "reconnectDelay": 10,
  "reportInterval": 60,
  "logdir": "alinode生产的日志放置的绝对路径,与NODE_LOG_DIR路径保持一致。如:/tmp/",
  "cmddir": "命令集路径,绝对路径,如:/Users/jacksontian/commands",
  "error_log": [
    "",
    "您的应用在业务层面产生的异常日志的路径",
    "例如:/root/.logs/error.#YYYY#-#MM#-#DD#.log",
    "可选,可多个"
  ],
  "packages": [
    "",
    "可以输入多个package.json的路径,用于帮助模块依赖的版本检查",
    "可选"
  ]
}

请注意,请勿修改配置中的server字段的值。配置中的#YYYY#、#MM#、#DD#是通配符,如果异常日志是按时间生成的,请使用它。其中应用 ID 和应用 Secret 请在应用设置页面获取。完成配置之后即可将 AgentX 启动:

nohup agentx config.json &

运行起来之后,就可以在应用主页看到连接上的实例。有一点值得注意:有些服务器的shell存在一些问题,为了不影响agentx的运行,建议退出时用exit命令主动退出。

启用alinode

alinode 运行时默认不启用任何功能,可以像普通的 node 进程一样来操作。当需要 alinode 的内核级监控时,请于启动进程前,添加如下两个环境变量:

  export ENABLE_NODE_LOG=YES
  export NODE_LOG_DIR=/tmp/

上面的NODE_LOG_DIR 必须跟AgentX 配置文件中的 logdir 字段保持一致, 且均必须使用绝对路径,例如 ~/alinode-logdir 是不能工作的, 同时需要确保该路径不需要 sudo 权限读写。注意:如果正在使用 pm2 ,请kill掉它的常驻进程,就是进程名叫做 PM2 God的那个,否则环境变量的设置无效。

应用性能监控

alinode提供了一系列的应用性能监控,包括:

  •  CPU:可以直观反映服务器的CPU资源占用情况。
  •  Mem/Heap:可以系统地观察到服务器的内存使用情况;内存堆信息可以查看进程占用的总内存(rss),申请的堆大小(heap_total),使用的堆大小(heap_used)。
  •  GC:进行GC监控(GC时间可以有效反馈进程的垃圾回收状况)、QPS以及APDEX/Handles等。

具体案例分析

案例一:内存泄露

定位内存泄露,其操作是进行Heapdump,将堆内存Dump出来生成Heapsnapshot文件,该文件可以通过Devtools进行分析,由于其是浏览器提供的工具,当文件较大时很难进行分析处理;alinode提供的heapdump service可以在服务器端分析Heapsnapshot文件,生成分析结果,再通过浏览器在线访问该分析结果,无需下载。

案例二:CPU飙高

对于CPU飙高的问题,首先需要进行CPU profiling,然后生成*.cpuprofile文件,然后通过dev tools工具分析性能数据,可以查看消耗CPU的代码。它的实际解决思路:使用异步操作替代阻塞型操作,让计算密集型的逻辑交给node.js线程池完成,不阻塞web主流程。

案例三:GC频繁

Garbage Collection (GC)是在内存中回收垃圾(Garbage)的过程,所谓的垃圾,就是内存中不会再被使用的部分。要分析GC频繁,首先需要生成GC日志,在Dev tools中没有生成GC日志的工具,可以采用node --trace_gc --trace_gc_verbose 应用启动文件.js或alinode收集,得到GC Trace log或*.heaptimeline文件;得到GC日志后,通过alinode GC分析工具进行分析。它的解决思路是:针对有类名的对象,直接使用 chrome dev tools查看即可;针对无类名的匿名对象,分析无类名的对象引用关系。

相关链接:

本文所涉及的项目链接总结如下:

关于分享者:

田永强,花名朴灵(Github:JacksonTian),阿里云飞天八部Alinode团队开发专家;《深入浅出Node.js》一书的作者,同时是Node.js项目的Collaborator。于2011年接触Node.js,当前主要从事Node.js的Web应用开发、Node.js内核研究,以及Node.js应用性能管理。擅长Node.js应用的性能调优、故障排查。



相关云产品:

基于 Node 运行时的应用性能管理解决方案alinode:http://alinode.aliyun.com/ 

时间: 2024-12-08 20:23:46

《深入浅出Node.js》作者分享:Node.js应用性能监控与问题诊断的相关文章

Express作者TJ告别Node.js奔向Go_node.js

首先这是一篇翻译自TJ 的 Farewell Node.js  ,我本人在看完这这篇文章之后确实是受到了一些冲击,但我并不认同作者的某些看法,比如我认为 Node.js 的package register 是其许多优势之一,反而 Go 在这方面却略显匮乏. 由于个人水平所限,在翻译的时候有许多不懂的地方,我也去作者博客.stackoverflow 上问了一些问题,获得了解答.翻译仍有许多不到位的地方,希望能获得指出意见. PS.  作为一位Node.js 的入门菜鸟,感谢TJ 的付出,一路走好.

node.js express安装及示例网站搭建方法(分享)_node.js

1.首先肯定是要安装Node.JS windows cmd依次输入如下命令: cd C:\Program Files\nodejs\ npm install -g express npm install -g express-generator 2.创建一个示例工程 windows cmd依次输入如下命令: cd C:\Program Files\nodejs\node_global express -e microblog //即ejs,-j(即jade) cd microblog npm i

深入浅析Node.js 事件循环_node.js

Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. (来源于Javascript是单线程又是异步的,但是这种语言有个共同的特点:它们是 event-driven 的.驱动它们的 event 来自一个异构的平台.) Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发. Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现. Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件

教你如何在Node.js中使用jQuery_node.js

想要在NodeJs中使用jQuery? 首先,我们得安装jquery, npm install jquery .安装后的版本是 3.1.0 接着,第一感觉我们会使用 var $ = require('jquery') . 将以下代码保存为app.js var $ = require('jquery') $("body").append("<div>TEST</div>"); console.log($("body").ht

什么是Node.js?Node.js详细介绍_node.js

简介 如果您听说过 Node,或者阅读过一些文章,宣称 Node 是多么多么的棒,那么您可能会想:"Node 究竟是什么东西?"尽管不是针对所有人的,但 Node 可能是某些人的正确选择. 为试图解释什么是 Node.js,本文探究了它能解决的问题,它如何工作,如何运行一个简单应用程序,最后,Node 何时是和何时不是一个好的解决方案.本文不涉及如何编写一个复杂的 Node 应用程序,也不是一份全面的 Node 教程.阅读本文应该有助于您决定是否应该学习 Node,以便将其用于您的业务

node.js入门教程_node.js

Node是个啥? 写个东西还是尽量面面俱到吧,所以有关基本概念的东西我也从网上选择性的拿了些下来,有些地方针对自己的理解有所改动,对这些概念性的东西有过了解的可选择跳过这段. 1.Node 是一个服务器端 JavaScript 解释器,可是真的以为JavaScript不错的同学学习Node就能轻松拿下,那么你就错了,总结:水深不深我还不知道,不过确实不浅. 2.Node 的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个物理机的连接代码.处理高并发和异步I/O是Node

学习Node.js模块机制_node.js

一.CommonJS的模块规范 Node与浏览器以及 W3C组织.CommonJS组织.ECMAScript之间的关系 Node借鉴CommonJS的Modules规范实现了一套模块系统,所以先来看看CommonJS的模块规范. CommonJS对模块的定义十分简单,主要分为模块引用.模块定义和模块标识3个部分. 1. 模块引用 模块引用的示例代码如下: var math = require('math'); 在CommonJS规范中,存在require()方法,这个方法接受模块标识,以此引入一

在Linux上用forever实现Node.js项目自启动_node.js

那么能否利用forever加启动脚本方式解决上述问题呢?答案当然是肯定的,只不过有点麻烦,而且forever官方缺少详细的配置文档.我在配置的时候也走了一些弯路,下面详细来说. 注:本文的实验环境是Ubuntu Server 12.04 LTS x86_64,在CentOS上的配置更简单一些 最早,我想着试试在/etc/rc.local中增加一句forever start xxx看看,结果发现Ubuntu(其他系统一样)就不鸟我,主要矛盾就是mongodb使用这种方式就可以跑起来,forever

朴灵:Node.js 将基于 io.js 跨过 1.0 直奔 2.0

从io.js的分裂到Node.js基金会,从外人看起来似乎如一场闹剧一般,然而这个过程中可以看到一个开源项目自身的成长.尽管io.js将归于Node.js基金会,像一个离家出走的孩子又回家一般,它的出走可能要被人忘记,但从当初的出发点来说,这场战役,io.js其实是赢家.穷则思变.不破不立是对Joyent较为恰当的形容.如果Joyent能提前想到这些,则不会有社区分裂的事情发生. Node.js处于停滞状态的开发和io.js的活跃情况之间,目前免不了大量的Merge工作.作为和解的条件之一,No