上一篇文章跟大家简单分享了如何在阿里云的环境中利用免费的百度统计、听云、友盟来追踪、统计、分析前端代码的运行状况和用户群体的数据,这一次的话,再从后端角度介绍下 APM 工具。

跟之前的一样,站在小站长的角度,也许付费可以获得更全面的功能,但我们仍然为了成本考虑优先使用免费的服务。这次介绍的是部署 Nodejs 的应用时,我们可以使用的两个工具—— 来自阿里云的 Node.js性能平台、以及仍然是听云出品的 听云Server。

关于使用 Nodejs 开发网站就不做过多介绍了,星空Online 所使用的框架为 Express,这是一个高性能的、对前后端研发而言入门门槛都相对较低的框架,并且它对 CPU 与内存的要求也不高,对于普通的乞丐版 ECS(1 核 1G)来说,通过 Docker 容器的隔离,一台机器上跑多个实例都是轻而易举。

Node.js 性能平台

Node.js 性能平台 是阿里云的对 Nodejs 运维提供的重磅工具,而且最为良心的是它还不要钱,除了常规的 CPU、内存监控之外,他还可以支持研发人员主动在程序中埋点,记录一些长耗时的操作。我们的站点访问速度不够理想时,有时可能并不是因为自己的代码写的不好,而是我们所依赖的第三方服务的性能有所减慢。

例如,我们购置的数据库性能不够高,那么在访问量变高时,可能会因为查询性能不够而导致整体耗时延长;我们的站点可能依赖了一个第三方接口,但是我们的出站带宽被占满了,这时发起网络请求的时间开销也随之变大。如果按照传统的方式去排查,我们可能只知道自己的某个页面变慢,但是如果缺乏对每一个流程做埋点,那可能就难以定位到底是哪里出了问题。通过 Node.js 性能平台提供的Trace 链路追踪功能,只需要简单的几行代码就能对关键的流程做好记录,如果某一次的请求变慢了,到底是哪个环节变慢我们就能很轻易的知道,这样就能有针对性的做出优化。

我们的站点是通过 Docker 进行部署的,所以我们无法使用直接在服务器安装性能平台组件的方式去使用。所幸阿里云提供了官方的镜像帮我们“预装”了性能平台的 Agent。之前我们在 Dockerfile 中,FROM 的镜像选择的是 node:8,我们在文档 容器镜像版本 中查了一下,最新的 Node v8.15.1 对应的底包为 3.14.1,所以我们只需要将 FROM 的内容更换为 registry.cn-hangzhou.aliyuncs.com/aliyun-node/alinode:3-alpine,就可以直接使用。特别提醒的是,如果是使用 ENTRYPOINT 作为镜像的启动入口的话,需要改为 CMD 的方式,否则无法正常启动 Agent。

如果需要进一步使用 Trace 链路追踪功能,就需要接入组件写相关的代码了(毕竟性能平台又不知道你代码的结构,所以必须要主动埋点),好在这个接入过程也不复杂。首先我们安装组件。

npm i @alicloud/opentracing -S

如果我们需要对所有请求均添加埋点,那么我们可以为 Express 实例追加一个中间件(MiddleWare),并加在最前方:

// app.ts
import opentracing from "@alicloud/opentracing";
const tracer = new opentracing.Tracer("APM");

app.use(function(req, res, next) {
  let parentSpan = tracer.startSpan("REQUEST");
  parentSpan.setTag(opentracing.Tags.PEER_HOSTNAME, req.hostname);
  parentSpan.setTag(opentracing.Tags.HTTP_METHOD, req.method.toUpperCase());
  parentSpan.setTag(opentracing.Tags.HTTP_URL, req.url);
  next();
  res.once("finish", () => {
    parentSpan.setTag(opentracing.Tags.HTTP_STATUS_CODE, res.statusCode);
    parentSpan.finish(req);
  });
});

只需这样短短几行代码,就能在我们的生产环境自动将所有的慢请求记录下来。

听云 Server

听云 除了有前端监控的组件之外,他也能为我们的 Node 应用提供 APM 支持。听云 Server 就是听云面向服务端进程提供的重要工具,这个服务也是依赖 Agent 来收集数据的,听云称之为“探针”,对于免费的用户来说,可以全局同时使用 3 个探针。在这里我为什么要用重点描述“同时”,那就是像运行在 Docker 中的 Nodejs 应用,虽然每次重新部署时旧的实例会被销毁,全新的实例又被创建,但是只要同时运行的实例在 3 个以内,那么就不需要做任何的调整和设置,听云后台会自动的收集新探针发来的结果。

那么有的朋友可能要问了,如果实例数超过 3 个会怎么样,会将整个监控都停掉吗?其实这个问题不用担心,根据实测,如果实例数超过 3 个,听云仅仅会提示你“探针授权数量不足”,运行中的前 3 个实例(启动的先后顺序)仍能正常的被记录,但是超过 3 个的部分的数据就不会显示在后台中。考虑到大部分的小站长可能做一个双机部署就已足够,所以并不太需要担心探针不足的问题。

听云的接入稍微有些复杂,如果是不在 Docker 运行的服务那么按照网站上介绍的安装方法即可,但是使用 Docker 的话就略显麻烦了。因为听云本地 Agent 的运行需要依赖于配置文件(tingyun.json),可是这个文件很难找到参考,标准的生成方法是安装组件后,通过运行setup命令来生成(就像npm init差不多,需要用户手动输入一些内容)。

可是 Docker 是更方便的工具,我们难道仅仅因为组件安装不方便我们就舍弃 Docker 吗?不需要。

听云官方建议大家通过手动下载探针脚本的方式安装至应用中,但是这种做法对做镜像包并不是特别的友好,我们其实只需要手动在我们的 package.json 的 dependencies 中添加依赖:"tingyun": "http://download.tingyun.com/agent/nodejs/1.7.1/tingyun-agent-nodejs-1.7.1.tar.gz"。在这种方式下,使用npm i一样可以正常的将包下载下来,然后使用node node_modules/tingyun/setup.js命令根据引导一步一步的完成,完成后会自动的生成一个 tingyun.json 文件,不要轻易删掉这个文件,无论部署在哪个环境,只要这个文件在,听云就能自动记录这个实例。

在这里要提示的是:如果你像我一样是使用的 typescript,setup.js 执行到最后时会因为找不到入口文件而失败,所以接入时还需要手动的在程序入口处手动引入听云的包。例如我的程序的最前端入口为 www.ts 文件,所以我就在这个文件的头部添加如下代码,就可以全部完成代码的安装了。

import "tingyun";

如果觉得听云的 3 个探针不够用,也可以联系他们的客服购买更多探针,成为他们的正式用户。成为正式用户后,听云可以为你保存 90 天的数据,比起免费用户的 1 天保存期来说是相当的长了。不过由于我也不清楚具体的价格,所以大家量力而行。


截至到今天,我们向大家依次介绍了自建 Nginx 日志的查询分析体系,免费的百度统计、听云 Browser、友盟 U-Web 保障前端性能,免费的阿里云 Node.js 性能平台、听云 Server 保障后端性能。通过这些工具可以让你有针对性的优化网站,使网站运行的越来越快、越来越稳定。