Node.js运维问题(一)

2,522 阅读5分钟
原文链接: zhuanlan.zhihu.com

鉴于前端技术更新日新月异,出于提升我所在团队的前端技术水准的需要,我在16年年底,向boss提出了,参考阿里的中途岛,采取了前后技术分离的架构的一整套方案。我们项目组整体的技术架构是node.js+java。就后端Java而言,16年Spring Cloud开始出现苗头,采用了微服务技术。就前端node.js而言,我们还是出于提升前端技术水准的目的,大胆的将node.js用来做前端的服务器,用于适配后端各种接口。

本文出于对node.js的运维问题介绍,就不在本文中讨论这样的架构以及业务特点或者适用场景等等。

Node.js除了前端工程化以外,在实现业务逻辑的时候,javascript的语法与面向对象编程的java相比,开发效率是快。

记得项目组在做前后端分离的时候,往往1个前端同学配置4个后端同学,完成一项业务需求。

但是,正是由于javascript的语言的特性,在服务器上运行代码的时候,很容易出现内存泄漏、以及CPU负载高的情况。

而市面上除了一些比较好的解决方案以外,就没有其他开源更为有效的监控体系。

在实际运维监控过程中,出现性能问题,并不是纯粹看CPU以及Memory这两项指标就能够解决所有问题,而是要能够在线去分析,在当时的那个情况下去分析。

目前市面上,就这个需求而言,相关的运维工具多多少少做的不是很好,解决运维痛点的并不是十全十美。当然了这些运维工具指向于以下:

  1. OneAPM、NewRelic为代表的在业务代码中硬性编码的运维工具,无法深入底层,剖析运行状况。他们只能看看CPU、memory,进程有无重启以及所谓的transaction等信息。很多时候,运维还需要能够在大流量下将当时的服务器dump,方便分析定位。可惜没有。
  2. 以pm2为代表的复杂运维工具,除了收费以外,过于复杂,复杂度远远超过了一般的web应用项目。在谷歌上搜索pm2的相关情况,有时能够发现内存泄漏,也就是pm2自己内存泄漏。不过,正是由于业务代码的不规范出现进程重启,恰好从某个角度解决了内存泄漏问题,不!应该是规避了它!因为重启进程,释放了内存!收费版本的pm2,直接使用v8-profiler,一个开源的第三方包,说白了是充分利用node.js的v8 api,内部实现了复杂的js逻辑。
  3. 以腾讯的TSW以及阿里的Pandora.js为代表的监控工具,虽然自带了或者不全是自带的dashBoard,但是他们也没有办法去深入底层,剖析运行时。
  4. @hyj1991同学编写的easy-monitor,结合了pm2以及tsw的部分特点,线下定位解决node.js内存泄漏问题。不过无法满足线上的情况。
  5. 其他的不予置评。

看完了市面上的这些node.js的运维工具,我们还有一个alinode。Alinode是@朴灵 大师等人搞出来的,据说保障了ali的众多业务线的运营稳定,什么15年的天猫双十一大火,甚至在github上开了专栏。

Alinode的特点就是能够在线定位profile node.js进程。这么神奇的东东,本质上是node.js改造过后,增加了一些新的特性。

让我记忆深刻的,有如下几点:

  1. 在线profile,dump,trace-gc
  2. 可视化dump文件,有时候生产的dump文件可能1个G,这超过了chrome-dev-tools自身的吞吐了、
  3. 无需更改任何业务代码,直接部署,全面兼容官方的node.js。

4,生成日志,agentx自动上报。

但是,对于我这内网的项目,不太可能将性能数据往外发,结合目前市面上的node.js监控项目,我们自己开发了一款node.js。

我们的node.js有如下的特点:

  1. ,无需更改任何代码,直接生成日志。
  2. 我们不像alinode一样占用node.js进程CPU数,而是采用go语言编写agent,实现高效的日志解析;
  3. 我们也能够实现在线dump 以及profile某个node.js进程

我们的模型如下:

我们的node.js项目结构如下:

进入bin文件夹后

我们看到有三个执行文件,

  1. node是编译完成后的node,二进制包;
  2. NodeAgent是用于解析生成日志并自动上报
  3. NodeKiller是用于实现linux下进程的通信桥梁;

我们也像alinode一样,自动在默认环境下生成日志

日志分为两块:

一个是系统级别的日志,如下图:

另外一个是异常级别的日志。

而nodeAgent的作用就是将这些日志以1分钟的频率自动上报给远程的服务器,用于实现数据的收集与处理。

解析后服务器端收到的数据如下:

我们模拟下在线dump;

我们在线dump以后,

通过chrome,我们就能看到当前堆快照有哪些对象。具体怎么分析,我们后面接着说。

由于篇幅的原因,我下一篇会完整介绍我们定制化node.js的一些更为深入的技术细节特点。