直播回顾视频:
以下内容是根据直播和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查看即可;针对无类名的匿名对象,分析无类名的对象引用关系。
相关链接:
本文所涉及的项目链接总结如下:
- NPM:https://www.npmjs.com/
- CNPM:https://npm.taobao.org/
- 命令集下载地址:https://github.com/aliyun-node/commands
- GC更多详细资料:http://alinode.aliyun.com/blog/37
- Alinode部署向导:http://alinode.aliyun.com/doc/deploy
关于分享者:
田永强,花名朴灵(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/