alinode 1.0.1新特性介绍

什么是alinode

alinode是阿里云alinode团队推出的改进版的node,通过升级内核代码,在不影响性能(部分功能提高性能)的基础上,无需用户代码做任何修改的前提下,达到在线监控,实时线上故障排查的目的。

目前在阿里系内部产品线已有广泛的使用。

为什么推出alinode

社区node用起来似乎很顺,也有些各种各样的npm包,甚至是有些APM厂商可以提供调试/监控等功能,而且开发者也可以提交PR到社区,为什么还要推出alinode?

  • npm上的调试工具,基本上都是本地调试用,无法用于生产环境
  • APM厂商提供的监控工具,需要增加探针到本地代码
    • 性能影响
    • 有些地方改变代码行为
    • 代码被入侵,总觉得不太放心
  • V8层面的patch,要迂回到V8社区,效率是一方面,一些针对服务端的node的patch并不适合浏览器,所以难以合并代码
  • 中文相关的feature,需要较大量修改V8
  • 在线调试功能,在整个内核上代码工作量比较大,而且需要配合一系列的分析工具

正是基于以上诸多原因,我们才决定推出alinode,帮node用户保驾护航。

alinode特性介绍

此次alinode推出以下新特性,需要强调的是,alinode没有修改node的api,只是增加了部分api,和后台输出性能日志,以达到虚拟机级别的性能监控和在线故障排查的目的。

注:要使用alinode新特性,需要配置两个环境变量

  • ENABLE_NODE_LOG=YES
  • NODE_LOG_DIR=/path/to/alinode/log

性能日志

alinode按天生成性能日志(设置环境变量 ENABLE_NODE_LOG=YES 写log到 NODE_LOG_DIR 指定的目录)。

性能日志包含以下功能:

  • 定时器相关数据
  • 堆空间数据
  • GC耗时数据
  • HTTP统计信息

配置环境变量ENABLE_NODE_LOG的值是YES,那么alinode启动后自动将日志功能打开

ENABLE_NODE_LOG=YES

配合agentx,可以将性能日志采集到alinode服务平台,从alinode的控制台可以查看到数据的可视化效果。

在线故障排查功能

线上故障排查是任何一个码农都头疼的问题,究其原因,很大的一部分是由于线上出现问题的时候,最直接的解决办法是重启应用。但是重启并不能从根本上解决问题,将解决问题的时机寄希望在线下重现问题上。然而线上环境业务复杂,条件多样,对于一些较为隐秘的问题,没有足够大而且多样的流量,根本无法在线下环境重现。

alinode推出的在线故障排查功能,力求帮助走出上述困境,线上出现问题的时候,或者预计将要出现问题之前,能够抓取现场,最大程度上协助问题排查。

以下功能都可以在线上机器运行时进行的操作,推荐通过使用alinode解决方案进行操作。
可以参考:一步一步部署alinode

在线生成heapdump

协助解决内存泄露故障,当线上机器出现内存泄露时,将v8的堆dump出来,然后分析,查看哪些对象占用了内存没有释放。

在线CPU profiling

协助解决代码运行CPU占用居高不下的问题,在CPU占用较高的时候,做3分钟的CPU profiling,然后分析,可以找出哪些JavaScript函数的耗时最久和调用栈最深。

在线Basic profile

Basic profiling可以详细到虚拟机级别的C/C++函数效率,适合有较多C/C++ addon的项目进行问题排查。

在线GC跟踪

相当于node以--trace_gc启动,不过是在线开启,3分钟后自动结束。

在线详细GC跟踪

相当于node以 --trace_gc --trace_gc_nvp --trace_fragmentation --trace_gc_verbose 启动,不过是在线开启,3分钟后自动结束。

API增强

alinode增加了几个API,以更好地支持中文与调试。

GBK编码支持

node(实际工作由V8完成)并不支持GBK编码,在用户需要gbk编码的场合,需要引入第三方js库支持,一般使用iconv-lite库。

alinode则已经原生支持GBK编码。使用示例:

var iconv = require('iconv-lite');

var content = ...
// content里面的是如下buffer,对应的字符串是   测试编码¤§¨°±·×à€¤§测试¨   
// <Buffer b2 e2 ca d4 b1 e0 c2 eb a1 e8 a1 ec a1 a7 a1 e3 a1 c0 a1 a4 a1 c1 a8 a4 80 a1 e8 a1 ec b2 e2 ca d4 a1 a7>


// 解码
if (Buffer.isEncoding('gbk')) {        // 查看编码是否支持
  content = content.toString('gbk'); // 如果支持,则调用原生接口进行解码,将buffer转成字符串
} else {
  content = iconv.decode(content, 'gbk');// 否则调用iconv-lite库进行解码
}

// 编码
if (Buffer.isEncoding('gbk')) {          // 查看编码是否支持
  content = new Buffer(content, 'gbk');  // 如果支持,则调用原生接口进行编码,将字符串转成buffer
} else {
  content = iconv.encode(content, encoding);// 否则调用iconv-lite进行编码
}

实测alinode的gbk编解码效率是iconv-lite的4倍左右(取决于内容中的中文占比)。

array.join对双字节(汉字)的支持

在如下的js代码中:

[str1, str2, str3].join(sep)

原生的node只有str1、str2、str3、sep都是ascii编码时才能走快速路径(效率更好)。

改进后str1、str2、str3、sep之中可以包含ucs2编码的字符(汉字是典型的代表),也会走快速路径。

用户在使用上没有任何感知。测试表明,纯中文性字符串能提高6-7倍,ASCII字符串保持一致,混合字符串则依赖中文比例。

欢迎使用

如果你想尝试alinode的功能,安装步骤在这里

如果你是在使用上有任何问题,欢迎与我们联系

结尾

有爱。