vlambda博客
学习文章列表

读书笔记《developing-microservices-with-node-js》监控微服务

Chapter 7. Monitoring Microservices

监控服务器一直是一个有争议的话题。它通常属于系统管理,软件工程师甚至不会靠近它,但我们正在失去监控的巨大好处之一:对故障做出快速反应的能力 。通过非常密切地监控我们的系统,我们几乎可以立即意识到问题,以便纠正问题的措施甚至可以使我们免于影响客户。除了监控之外,还有性能的概念。通过了解我们的系统在加载期间的行为,我们将能够预测扩展系统的必要性。在本章中,我们将讨论如何监控服务器,特别是微服务,以保持系统的稳定性。

在本章中,我们将介绍以下主题:

  • 监控服务

  • 使用 PM2 和 Keymetrics 进行监控

  • 监控指标

  • Simian Army – 来自 Spotify 的主动监控

  • 吞吐量和性能下降

Monitoring services


在监控 微服务时,我们对几种不同类型的指标感兴趣。第一大组指标是硬件资源,描述如下:

  • 内存指标:这表示我们的系统中剩余多少内存或被 我们的应用

  • CPU使用率:正如 顾名思义,这表示有多少CPU我们在给定的时间使用

  • 磁盘利用率:这个表示物理硬盘的I/O压力驱动器

第二大组是应用指标,如下:

  • 每个时间单位的错误数

  • 每个时间单位的调用次数

  • 响应时间

即使 两个组都相互关联,并且硬件问题会影响应用程序性能(反之亦然),但必须了解所有这些组。

如果我们的服务器是 Linux 机器,硬件指标很容易查询。在 Linux 上,硬件资源的所有魔力都发生在 /proc 文件夹中。该文件夹由系统内核维护,并包含有关系统如何在系统中的许多方面表现的文件。

软件指标更难收集,我们将使用 PM2 创建者的 Keymetrics 来监控我们的 Node.js 应用程序。

Monitoring using PM2 and Keymetrics

正如我们之前所见,PM2 是运行 Node 应用程序的非常强大的工具,但它也非常 擅长监控独立应用程序 在生产服务器中。但是,根据您的业务案例,它并不总是总是很容易获得生产。

PM2 的创建者 通过创建 Keymetrics 解决了这个问题。 Keymetrics 是一个软件即服务SaaS)组件允许PM2通过网络向其网站发送监控数据,如下图所示(如发现https://keymetrics.io/):

读书笔记《developing-microservices-with-node-js》监控微服务

尽管 Keymetrics 不是免费的,但它提供了一个免费层来演示它的工作原理。我们将在本章中使用它。

我们首先需要做的 就是注册一个用户。一旦我们可以访问我们的帐户,我们应该会看到类似于以下屏幕的内容:

读书笔记《developing-microservices-with-node-js》监控微服务

此屏幕 要求我们创建一个存储桶。 Keymetrics 使用存储桶概念来定义上下文。例如,如果我们的组织有不同的区域(支付、客户服务等),每个区域都有不同的服务器,我们可以监控一个存储桶中的所有服务器。一个存储桶中可以拥有多少台服务器没有限制。甚至可以将所有组织放在同一个存储桶中,以便轻松访问所有内容。

让我们创建一个名为 Monitoring Test 的存储桶,如下图所示:

读书笔记《developing-microservices-with-node-js》监控微服务

很简单,一旦我们点击创建桶,Keymetrics 将向我们显示一个屏幕,其中包含开始监控我们的应用所需的信息,如 如下图所示:

读书笔记《developing-microservices-with-node-js》监控微服务

如您所见, 屏幕显示有关 Keymetrics 使用的 私钥的信息.通常,与 任何人共享此密钥是 一个非常糟糕的主意。

如屏幕所示,下一步是配置 PM2 以将数据推送到 Keymetrics。还有关于使 Keymetrics 工作所需的网络的有用信息:

  • PM2 将在 Keymetrics 上将数据推送到端口 80

  • Keymetrics 将通过端口 43554 将数据推送给我们

通常,在大型组织中,网络存在一些限制,但如果您在家中进行测试,一切都应该立即生效。

为了使 PM2 能够将指标发送到 Keymetrics,我们需要安装一个名为 pm2-server-monit 的 PM2 模块。这是一个相当简单的任务:

pm2 install pm2-server-monit

这将产生类似于以下内容的输出:

读书笔记《developing-microservices-with-node-js》监控微服务

让我们运行建议的命令:

pm2 link fan7p32fnysuuw8 znlz25frrcwakg6 my-server

在这个 案例中,我已将 [server name] 替换为 my -服务器 。服务器名称没有限制;但是,在将 Keymetrics 推广到实际系统中时,建议 选择一个描述性名称,以便轻松识别仪表板中的服务器。

前面的命令将产生类似于下图的输出:

读书笔记《developing-microservices-with-node-js》监控微服务

这表明一切顺利,我们的应用程序已准备好通过 Keymetrics 进行监控, 可以在 https://app.keymetrics.io/,如下:

读书笔记《developing-microservices-with-node-js》监控微服务

现在,我们的 服务器出现在界面中。正如我们之前 所述,此存储桶可以监控 不同的服务器。创建了一个简单的虚拟 机器,正如您在屏幕底部看到的那样,Keymetrics 为我们提供了要执行的命令,以便添加另一个服务器。在这种情况下,由于我们使用的是免费访问 Keymetrics,所以我们只能监控一台服务器。

让我们看看 Keymetrics 可以为我们提供什么。乍一看,我们可以看到有趣的指标,例如 CPU 使用率、可用内存、可用磁盘等。

所有这些都是硬件指标,表明我们的系统是如何运行的。在压力下,它们是指出需要更多硬件资源的完美指标。

通常,硬件资源是应用程序失败的主要指标。现在,我们将了解如何使用 Keymetrics 来诊断问题。

Diagnosing problems

由于缺陷的性质,内存泄漏 通常是一个难以解决的问题。看看下面的代码。

让我们使用一个简单的 seneca.act() 动作运行 程序:

var seneca = require('seneca')();

var names = [];

seneca.add({cmd: 'memory-leak'}, function(args, done){
  names.push(args.name);
  greetings = "Hello " + args.name;
  done(null ,{result: greetings});
});

seneca.act({cmd: 'memory-leak', name: 'David'}, function(err, response) {
  console.log(response);
});

这个程序有一个非常明显的内存泄漏,显然,我的意思是它被写得很明显。 names 数组将无限增长。在前面的示例中,这没什么大不了的,因为我们的应用程序是一个脚本,它会在不将状态保存在内存中的情况下启动和结束。

Tip

请记住,如果不使用 var 关键字,JavaScript 会在全局范围内分配变量。

当其他人在应用程序的不同部分重新利用我们的代码时,问题就出现了。

假设我们的系统发展到需要一个微服务来迎接新客户(或交付个人信息的初始有效负载,例如姓名、偏好、配置等)。以下代码可能是如何构建它的一个很好的例子:

var seneca = require('seneca')();

var names = [];

seneca.add({cmd: 'memory-leak'}, function(args, done){
  names.push(args.name);
  greetings = "Hello " + args.name;
  done(null ,{result: greetings});
});

seneca.listen(null, {port: 8080});

在此示例中,Seneca 将通过 HTTP 侦听来自 Seneca 客户端或其他类型系统的请求,例如 ,如 卷曲。当我们运行应用程序时:

node index.js
2016-02-14T13:30:26.748Z szwj2mazorea/1455456626740/40489/- INFO hello Seneca/1.1.0/szwj2mazorea/1455456626740/40489/-
2016-02-14T13:30:27.003Z szwj2mazorea/1455456626740/40489/- INFO listen {port:8080}

然后从 另一个终端,我们使用 curl 作为我们微服务的客户端,一切都会顺利进行,我们的内存泄漏不会被注意到:

curl -d '{"cmd": "memory-leak", "name":"David"}' http://127.0.0.1:8080/act
{"result":"Hello David"}%

但是,我们将使用 Keymetrics 来找出问题所在。我们需要做的第一件事是使用 PM2 运行我们的程序。为此,我们运行以下命令:

pm2 start index.js

此命令将产生以下输出:

读书笔记《developing-microservices-with-node-js》监控微服务

让我们在下面解释输出:

  • 第一行为我们提供了有关与 Keymetrics 集成的信息。公钥、服务器名称和访问 Keymetrics 的 URL 等数据。

  • 在第一个表中,我们可以看到正在运行的应用程序的名称,以及一些关于内存、正常运行时间、CPU 等的统计信息。

  • 在第二个表中,我们可以看到与 pm2-server-monit PM2 模块相关的信息。

现在,让我们去 Keymetrics 看看发生了什么:

读书笔记《developing-microservices-with-node-js》监控微服务

该应用程序现在已在 Keymetrics 中注册,可以在控制面板中看到

如您所见, 现在我们的应用程序出现在 Keymetrics 中。

直接,我们可以看到我们的应用程序非常有用的东西。其中之一是使用的内存。这是指示内存泄漏的指标,因为它会不断增长。

现在,我们将强制内存泄漏导致我们的应用程序出现问题。在这种情况下,我们唯一需要做的就是启动我们的服务器(我们之前编写的小型应用程序)并发出大量请求:

for i in {0..100000}
do
  curl -d '{"cmd": "memory-leak", "name":"David"}' http://127.0.0.1:8080/act
done

就像小 bash 脚本一样简单,这就是在我们的应用程序中打开潘多拉魔盒所需的全部内容:

读书笔记《developing-microservices-with-node-js》监控微服务

应用程序现在显示高负载(36% 的 CPU 和增加的内存使用量高达 167 MB)

上图 显示了在我们的系统中运行请求循环的影响。让我们在下面解释它:

  • 我们应用程序中的 CPU 已达到 11%,平均循环延迟为 1.82 毫秒。关于我们的系统,由于应用程序和 bash 脚本都使用了大量资源,因此整体 CPU 利用率已上升到 36.11% .

  • 内存消耗从 81.9 MB 飙升至 167.6 MB。如您所见,内存分配图上的线并没有直线上升,这是由于垃圾收集造成的。垃圾回收是 Node.js 框架中的一项活动,其中未引用的对象从内存中释放出来,允许我们的系统重用硬件资源。

  • 关于错误,我们的应用程序一直稳定,出现 0 错误(我们稍后会回到本节)。

现在,一旦 我们的 bash 脚本完成(我手动停止它,因为它可能需要大量的资源和时间来完成),我们可以再次看到在以下屏幕截图中我们的系统发生了什么:

读书笔记《developing-microservices-with-node-js》监控微服务

我们可以看到CPU恢复正常了,但是内存呢?我们的应用程序消耗的内存没有被释放,因为我们的程序有内存泄漏,只要我们的变量引用了消耗的内存(记住 names数组正在积累越来越多的名称),它不会被释放。

在这种情况下,我们有一个非常简单的示例,可以清楚地显示内存泄漏的位置,但在复杂的应用程序中,并不总是很明显。尤其是这个错误,永远不会 显示为问题,因为我们可能经常部署应用程序的新版本而没有意识到这一点。

Monitoring application exceptions

应用程序错误是当我们的应用程序无法处理意外情况时发生的事件。诸如将数字除以零或尝试访问我们的应用程序 的未定义属性 通常会导致这类问题。

在使用诸如 Tomcat 之类的多线程框架(语言)时,我们的一个线程因异常而死亡的事实通常只影响一位客户(持有该线程的客户)。然而,在 Node.js 中,当我们的应用程序终止时,冒泡异常可能是一个重大问题。

PM2 和 Seneca 在保持其活动性方面做得非常好,因为 PM2 将在某些事情导致它停止时重新启动我们的应用程序,并且如果其中一个操作发生异常,Seneca 不会让应用程序死亡。

Keymetrics 开发了一个名为 pmx 的模块,我们可以使用它以编程方式获取错误警报:

var seneca = require('seneca')();

var pmx = require('pmx');

var names = [];

seneca.add({cmd: 'exception'}, function(args, done){
  pmx.notify(new Error("Unexpected Exception!"));
  
  done(null ,{result: 100/args.number}); 
});

seneca.listen({port: 8085});

它很简单且具有自我描述性:如果作为参数发送的数字为零,则向 Keymetrics 发送异常的操作。如果我们运行它,我们将得到以下输出:

读书笔记《developing-microservices-with-node-js》监控微服务

现在我们需要在中访问服务器才能导致错误。正如我们之前所做的,我们将使用 curl 执行此操作:

curl -d '{"cmd": "exception", "number": "0"}' http://localhost:8085/act
{"result":null}%

现在,当我们转到 Keymetrics 时,我们可以看到记录了一个错误,如下图所示:

读书笔记《developing-microservices-with-node-js》监控微服务

Keymetrics 另一个有趣的地方是警报的配置。由于 PM2 发送关于我们系统中几乎每个指标的数据,我们能够在我们认为对我们的应用程序健康的阈值上配置 Keymetrics。

这非常方便,因为我们可以将通知集成到 我们的公司聊天(类似于 Slack),并在不存在时实时提醒在我们的应用程序中正确运行。

Custom metrics

Keymetrics 还 允许我们使用探针。探针是一种自定义指标, 由应用程序以编程方式发送到 Keymetrics。

Keymetrics 的原生库允许我们直接推送 不同类型的值。我们将看到最有用的。

Simple metric

顾名思义,一个简单的指标 是一个非常基本的指标,其中开发人员可以将值设置为发送到 Keymetrics 的数据:

var seneca = require('seneca')();
var pmx = require("pmx").init({
  http: true,
  errors: true,
  custom_probes: true,
  network: true,
  ports: true
});
var names = [];
var probe = pmx.probe();

var meter = probe.metric({
  name      : 'Last call'
});

seneca.add({cmd: 'last-call'}, function(args, done){
  console.log(meter);
  meter.set(new Date().toISOString());
  done(null, {result: "done!"});
});

seneca.listen({port: 8085});

在这种情况下,指标会将最后一次调用操作的时间发送到 Keymetrics:

读书笔记《developing-microservices-with-node-js》监控微服务

该指标的 配置 不存在:

var probe = pmx.probe();

var meter = probe.metric({
  name      : 'Last call'
});

这个指标没有复杂性。

Counter

这个指标对于计算事件发生的次数非常有用:

var seneca = require('seneca')();
var pmx = require("pmx").init({
  http: true,
  errors: true,
  custom_probes: true,
  network: true,
  ports: true
});
var names = [];
var probe = pmx.probe();

var counter = probe.counter({
  name : 'Number of calls'
});

seneca.add({cmd: 'counter'}, function(args, done){
  counter.inc();
  done(null, {result: "done!"});
});

seneca.listen({port: 8085});

在前面的代码中,我们可以看到每次调用操作计数器时计数器是如何递增的。

该指标将 还允许我们减少调用 dec() 方法的值 在柜台上:

counter.dec();
Average calculated values

这个metric可以让我们记录一个事件发生的时间,它会自动计算每个时间单位的事件数。计算平均值非常有用,是衡量系统负载的好工具。我们来看一个简单的例子,如下:

var seneca = require('seneca')();
var pmx = require("pmx").init({
  http: true,
  errors: true,
  custom_probes: true,
  network: true,
  ports: true
});
var names = [];
var probe = pmx.probe();

var meter = probe.meter({
  name      : 'Calls per minute',
  samples   : 60,
  timeframe : 3600
});

seneca.add({cmd: 'calls-minute'}, function(args, done){
  meter.mark();
  done(null, {result: "done!"});
});

seneca.listen({port: 8085});

前面的代码创建了一个探测并将一个名为 Calls per minute 的新指标发送到 Keymetrics。

现在,如果我们多次运行应用程序和以下命令,指标将显示在以下 Keymetrics 界面中:

curl -d '{"cmd": "calls-minute"}' http://localhost:8085/act
读书笔记《developing-microservices-with-node-js》监控微服务

如您所见, 有一个名为 每分钟通话次数。配置此指标的关键在于以下初始化:

var meter = probe.meter({
  name      : 'Calls per minute',
  samples   : 60,
  timeframe : 3600
});

如您所见,指标的名称在配置字典以及两个参数中:samplestimeframe

samples 参数对应于我们要对指标进行评分的区间;在这种情况下,它是每分钟的调用次数,因此速率为 60 秒。

另一方面,timeframe 参数是我们希望 Keymetrics 将数据保存多长时间,或者用更简单的词来表达,它是度量标准的时间范围进行分析。

Simian Army – the active monitoring from Spotify


Spotify构建面向微服务的参考公司之一<一个 id="id582" class="indexterm"> 应用程序。当归结为提出新想法时,他们极具创造力和才华。

其中我最喜欢的想法之一就是他们所说的猿猴军队。我喜欢称它为 主动监控

在这本书中,我多次谈到人类在执行不同任务时是如何失败的。无论您为创建软件付出了多少努力,都会出现影响系统稳定性的错误。

这是一个大问题,但是当现代云提供商使用脚本自动化您的基础架构时,这将成为一个大问题。

想一想,如果在数千台服务器池中,其中三台的 时区与其余服务器不同步,会发生什么情况?好吧,根据您系统的性质,它可能很好,也可能很重要。你能想象你的银行给你一份交易混乱的声明吗?

Spotify 通过创建许多软件代理(在我们系统的不同机器中移动的程序)解决(或缓解)了上述问题,以不同目的的不同种类的猴子命名它们,以确保其基础设施的稳健性。让我们进一步解释一下。

您可能知道,如果您之前使用过 Amazon Web Services,机器和计算元素被划分为区域(欧盟、澳大利亚、美国等),并且在每个区域内,都有可用区,如图所示下图:

读书笔记《developing-microservices-with-node-js》监控微服务

这使 我们这些工程师能够创建软件和基础架构,而不会遇到我们所谓的单点故障。

Note

单点故障是系统中发生故障的条件单个元素将导致系统行为异常。

这种配置向 Spotify 的工程师提出了一些问题,如下所示:

  • 如果我们盲目地相信我们的设计而不测试我们是否真的有任何故障点会发生什么?

  • 如果一个完整的可用区或区域出现故障会发生什么?

  • 如果由于某种原因出现异常延迟,我们的应用程序将如何表现?

为了回答所有这些问题,Netflix 创建了各种代理。代理是运行在系统(在本例中为我们的微服务系统)上并执行不同操作的软件,例如检查硬件、测量网络延迟等。代理的想法并不新鲜,但直到现在,它的应用几乎是一个未来主义的主题让我们看看以下由 Netflix 创建的代理:

  • Chaos Monkey:这个代理在给定的情况下断开健康机器与网络的连接可用区。这可确保在可用区内没有单点故障。因此,如果我们的应用程序在四个节点之间保持平衡,那么当 Chaos Monkey 启动时,它将断开这四台机器中的一台。

  • Chaos Gorilla:这个类似于Chaos Monkey,Chaos Gorilla会断开连接一个完整的可用区域,以验证 Netflix 服务是否重新平衡到其他可用区域。也就是说,混沌猩猩是混沌猴的大哥;它不是在服务器级别运行,而是在分区级别运行。

  • Latency Monkey:这个代理负责在连接中引入人工延迟.延迟通常是开发系统时几乎不会考虑的问题,但在构建微服务架构时却是一个非常微妙的主题:一个节点的延迟可能会影响整个系统的质量。当服务耗尽资源时,通常第一个迹象是响应的延迟;因此,Latency Monkey 是了解我们的系统在压力下会如何表现的好方法

  • Doctor Monkey:健康检查是我们应用程序中的一个端点,它返回一个 HTTP 200(如果一切正确)和 500 错误代码(如果应用程序中存在问题)。猴子医生是一个代理,它将随机执行我们应用程序中节点的健康检查并报告有故障的节点以替换它们。

  • 10-18 Monkey这样的组织是全球性的,所以他们需要具有语言意识(当然,当您的母语是西班牙语时,您不希望获得德语网站)。 10-18 Monkey 报告配置错误的实例。

还有一些其他的代理,但我只是想向您解释主动监控。当然,这种类型的监控对于小型组织来说是遥不可及的,但最好了解它们的存在,这样我们就可以得到启发来建立我们的监控程序。

Note

该代码在以下存储库中的 Apache 许可下可用:

https://github.com/Netflix/SimianArmy

一般来说,这种主动监控遵循尽早失败的理念,即其中,我是个大能手。无论您的系统中的缺陷有多大或有多严重,您都希望尽快找到它,理想情况下,不要影响任何客户。

Throughput and performance degradation

吞吐量对于我们的应用程序来说就像每月生产对于 一个工厂。它是一种度量单位,可以指示我们的应用程序如何执行并回答系统的多少问题。

非常接近吞吐量,我们可以测量另一个单位:延迟

延迟是回答多长时间问题的性能单位。

让我们考虑以下示例:

我们的应用程序是一个基于微服务的架构,负责计算申请人的信用评级以提取抵押贷款。由于我们有大量客户(这是一个很好的问题),我们决定分批处理申请。让我们围绕它画一个小算法:

var seneca = require('seneca')();
var senecaPendingApplications = require('seneca').client({type: 'tcp', 
  port: 8002, 
  host: "192.168.1.2"});
  var senecaCreditRatingCalculator = require('seneca').client({type: 'tcp', 
  port: 8002, 
  host: "192.168.1.3"});

seneca.add({cmd: 'mortgages', action: 'calculate'}, function(args, callback) {
  senecaPendingApplications.act({
    cmd: 'applications', 
    section: 'mortgages', 
    custmers: args.customers}, function(err, responseApplications) {
      senecaCreditRatingCalculator.act({cmd: 'rating', customers: args.customers}, function(err, response) {

        processApplications(response.ratings, 
        responseApplications.applications,
        args.customers
      );
    });
  });
});

这是一个小的 和简单的 Seneca 应用程序(这只是 理论上的,不要' t 尝试运行它,因为缺少很多代码!)充当其他两个微服务的客户端,如下所示:

  • 第一个获取待处理的抵押贷款申请列表

  • 第二个获取我们请求的客户的信用评级列表

这可能是处理抵押贷款申请的真实情况。平心而论,我过去曾在一个非常相似的系统上工作过,尽管它要复杂得多,但工作流程非常相似。

让我们谈谈吞吐量和延迟。想象一下,我们有相当多的抵押贷款要处理,而系统运行不正常:网络没有达到应有的速度,并且正在经历一些中断。

其中一些应用程序将丢失,需要重试。在理想条件下,我们的系统每小时产生 500 个应用程序的吞吐量,处理每个应用程序的平均延迟时间为 7.2 秒。但是,今天,正如我们之前所说,该系统并非处于最佳状态。我们每小时只处理 270 份申请,平均需要 13.3 秒来处理一份抵押申请。

如您所见,通过延迟和吞吐量,我们可以衡量我们的业务交易相对于先前体验的表现;我们以正常产能的 54% 运营。

这可能是一个严重的问题。平心而论,像这样的下降应该会在我们的系统中敲响所有警报,因为我们的基础设施中正在发生一些非常严重的事情;但是,如果我们在构建系统时足够聪明,性能将会下降,但我们的系统不会停止工作。这可以通过使用断路器和队列技术 (例如 RabbitMQ< /跨度>。

排队 是展示如何将人类行为应用于 IT 系统的最佳示例之一。说真的,我们可以轻松地将软件组件解耦,将简单的消息作为连接点,我们的服务可以产生或使用这些消息,这在编写复杂软件时给了我们很大的优势。

通过 HTTP 排队的另一个优点是,如果网络中断,则 HTTP 消息会丢失。

我们需要 围绕这样一个事实来构建我们的应用程序:它要么完全 成功,要么错误。使用 RabbitMQ 等队列技术,我们的消息传递是异步的,因此我们无需担心间歇性故障:只要我们可以将消息传递到适当的队列,它将一直持续到客户端能够使用它(或发生消息超时)

这使我们能够解决基础设施中的间歇性错误,并基于队列周围的通信构建更强大的应用程序。

同样,Seneca 让我们的生活变得非常轻松:构建 Seneca 框架的插件系统使编写传输插件成为一项相当简单的任务。

Note

RabbitMQ transport 插件可以在以下 GitHub 存储库中找到:

https://github.com/senecajs/seneca-rabbitmq-transport

传输插件很少,我们也可以创建自己的(或修改现有的!)以满足我们的需求。

如果您快速浏览一下 RabbitMQ 插件(仅作为示例),我们编写传输插件唯一需要做的就是覆盖以下两个 Seneca 操作:

  • seneca.add({role: 'transport', hook: 'listen', type: 'rabbitmq'}, ...)

  • seneca.add({role: 'transport', hook: 'client', type: 'rabbitmq'}, ...)

使用排队技术,我们的系统将对间歇性故障更具弹性,我们将能够降低性能而不是由于以下原因而陷入灾难性故障丢失的消息。

Summary


在本章中,我们通过 Keymetrics 深入研究了 PM2 监测。我们学会了如何进行严格的监控,以便我们快速了解应用程序中的故障。

在软件开发生命周期中,QA 阶段在我看来是最重要的阶段之一:无论您的代码看起来多么好,如果它不起作用,那就没用了。但是,如果我必须选择工程师应该更加重视的另一个阶段,那就是部署,更具体地说,是在每次部署之后进行的监控。如果您立即收到错误报告,则反应可能会足够快,以避免出现更大的问题,例如数据损坏或客户抱怨。

我们还看到了 Netflix 在他们的系统上进行的主动监控的示例,即使您的公司可能无法做到这一点,它也可以激发好的想法和实践来监控您的软件。

Keymetrics 只是一个符合 Node.js 要求的示例,因为它与 PM2 集成得非常好,但也有其他很好的监控系统,例如 AppDynamics ,或者如果您想购买内部软件,您可以使用 Nagios。关键是清楚你需要在应用程序中监控什么,然后找到最好的供应商。

监控 Node.js 应用程序的另外两个不错的选择是 StrongLoop 和 New Relic。它们都与 Keymetrics 走在同一条线上,但它们更适用于大型系统,尤其是 StrongLoop,它面向用 Node.js 编写的应用程序,面向微服务。