监控(5)- 黑/白盒监控

最后更新:2020-07-05

1. 什么是黑/白盒监控

黑盒监控指的是监控外部用户可见的系统行为,白盒监控指的是监控内部暴露出来的指标信息。它们一个对外,一个对内。二者在功能上有 2 点区别。

  • 监控角度不同:黑盒更偏向于外侧,你可以理解为是通过某个功能或者具体的某个接口来观察,它并不清楚内部是如何实现的;而白盒则更倾向于从内侧监控,它是代码层面的,从内部的视角来解读整个系统。
  • 面向对象不同:黑盒更倾向于看到这个问题的现象,比如某个端口挂掉了无法再提供服务,它面向的是当下所发生的故障;白盒则更加倾向于面向产生问题的原因,比如我们在日志中可以通过堆栈信息分析出故障的根源。

白盒监控有时是面向问题,有时是面向问题的原因的,它的监控对象会根据监控的内容改变。假设白盒在接口层反映接口耗时比较长,此时可以认定白盒面向的是“耗时长”这一问题。但同时,白盒监控也会监控到与这个接口相关联的数据库出现了严重的慢查询。慢查询是接口耗时较长的原因,这时候我们就可以认定白盒是面向原因的。

2. 黑盒监控

黑盒中的监控一般可以细分为如下的 4 类内容。

  • 端口状态:通过程序检测具体业务的端口是否存活。可以简单确定程序是否有在提供服务,如果端口都无法连接,那么肯定是系统出现了问题。通常我们也会结合进程检测使用,如果进程存活,但是端口不存在,则说明可能程序存在某些问题,没有将服务暴露出来。
  • 证书检测:通过检测证书是否有效,确认用户是否可以正常访问。现在的网站服务基本都是使用的 HTTPS,如果证书出现了问题,则可能是浏览器认定为不安全,阻止了用户访问。
  • 探活:通过心跳检测来判定服务是否存活,比如定期通过具体的某个接口检测我们的服务是否运行正常。如果在这里出现异常,则说明我们的系统存在问题。在 Dubbo 中就有心跳机制来保证双方的链接,这也算是一种探活
  • 端到端功能检测:这个就相对复杂一些。通常是通过定期进行端到端的测试,结合业务流程感知业务是否在执行正常,比如我们可以通过 UI 或者接口自动化测试工具,来确认页面中返回的数据或者数据是否是正确的。

不难看出,它其实更偏向确认功能是否可用。黑盒监控的理解门槛相对较低,即便是一个从来没参与过这个项目的开发人员,都可以对这些数据进行验证、确认。

3. 白盒监控

白盒监控中重要的数据维度:

  • 日志:通过日志记录可以了解到程序的运行状态,程序中是否存在异常。

  • 指标:数值形式的指标可以帮助我们了解到系统中的数据走向、流量情况等。

  • 链路追踪:我们可以细粒度到程序的代码行级别来将链路可视化,这可以帮助我们了解程序的执行流程。

在系统中,我们会大量运用白盒监控来查看问题或是分析问题产生的原因。黑盒所监控的内容更偏向用户。比如当系统出现问题时,我们可以通过白盒查看到问题的原因,但是并不一定能够知道这个问题在用户那里是怎么表现的。如果由我们去想象,可能和真实的情况会有一定的出入,此时黑盒就可以展现出在用户端的真实表现形式。所以,黑盒和白盒之间并没有优劣的对比,它们各自有各自偏向的重点,将两者结合起来使用才是在监控中最有效的方式。

4. 黄金指标

黄金指标。黄金指标是 Google 针对大量分布式监控的经验总结,它可以在服务级别帮助衡量终端用户体验、服务中断、业务影响等层面的问题,有 4 类指标信息,分为错误、延迟、流量和饱和度。无论你监控的数据再复杂、再令人眼花缭乱,都可以套用在这 4 类上。

4.1. 错误

错误指的是当前系统所有发生过的错误请求,我们可以通过错误请求个数计算出相应的错误率。这个我想应该很容易理解,只要是程序运行,就肯定会因为某些原因而导致错误,可能是其他系统的组件导致的,也有可能是程序代码中自身的问题。

有 3 种比较常见的错误类型,我们这里以 HTTP 的接口举例:

  • 显示错误:指可以立即看出来的错误。比如在 HTTP 请求中,响应状态码出现 500,则可以认定为是显示错误。
  • 隐式错误:指表面上显示完全正确,但是在数据中已经出现异常的错误。响应状态码为 200 可以认定为成功,但如果业务在返回的数据结构中被认定为是错误,那这个错误就是隐式的。
  • 策略导致错误:与第二种类似,都是在表面上显示正确,但是可能因为某种策略被认定为错误。比如某个接口在 1s 时返回,因为已经接收到了数据,所以被认定为成功。但我们的策略限制 500ms 内才算完成,因此这个数据会被记录为错误,这就是策略导致的。在 RPC 的提供者消费者模式中这个情况也很常见。

在基础层中,我们可以把系统宕机、进程或者端口挂掉、网络丢包这样的情况认定为是故障。在业务层中,监控的内容也就相对比较多了,比如 Dubbo 调用出错、日志中出现的错误,都是可以被认定为“错误”的指标。

4.2. 延迟

延迟指的是服务在处理请求时花费的时间。我们经常说的接口耗时、响应时长指的就是延迟。在这里需要注意一点:一般在统计延迟时,并不会把成功或者错误的信息分开统计。这样的统计方式会使我们更难了解到真实的情况,所以在统计时常常需要把它们区分开。以一个 HTTP 接口为例,响应状态码正确的(200)和错误的(500)请求,它们的耗时一定会有差别,因为正确的请求走完了全流程,而错误的可能只进行了某一部分流程,我们就需要把这两个请求的耗时在统计时分别记录

在基础层中,我们可以监控 I/O 等待、网络延迟等信息。在业务层中,则可以监控接口调用的耗时、MySQL 查询的耗时等信息。

延迟在系统中是一个十分关键的指标,很多时候我们的服务并不会产生错误,但很可能会有延迟,延迟在 HTTP 层会影响用户体验,在数据库中出现高延迟会导致请求错误,这是我们需要着重关注的。

4.3. 流量

流量是表现系统负载情况的数据,比如我们常见的 QPS、UV。通过这个指标我们能确切了解到服务当前承受了多大的压力,请求量和处理量有多大。我们常说的容量规划,其实是流量规划。通过流量,我们可以得知当前系统运行的状况,是否到达了它的负荷上限。

在基础层中,常见的监控指标有磁盘的读写速度、网络 I/O 情况等。在业务层中则有请求量、MySQL 查询次数等等。

通过观察流量相关的指标,可以了解到是否存在突增突降的情况,从而判断是否遭受到了攻击或者是否在进行某些活动。

4.4. 饱和度

饱和度通常是指某个资源的使用率。通常指的是我们通过容量的最大值和现在的使用量,来判断这个容量是否“满”了。某些程序,如果资源饱和度过高,可能会导致执行缓慢,甚至无法使用。比如 CPU 使用率如果达到 100%,会出现执行缓慢;Dubbo 进行 RPC 调用时,如果线程池没有可用的线程数,则会使业务受到阻碍。

饱和度一般也会配合其他指标一起使用,比如在使用网络 I/O 时,网卡都是有流量上限的,我们通过流量上限值和当前网络 I/O 的使用情况,可以得知相应的饱和度。饱和度是衡量我们这个系统是否到达瓶颈的关键。如饱和度过高,这时候就需要考虑扩容、减少数据量或是其他降低饱和度的操作了。

在基础层中,需要监控的指标有 CPU 使用率、I/O 使用率、句柄使用情况等。在业务层中则会有线程池的线程使用数、JVM 中的堆内存使用率等信息。

5. 参考资料

《分布式链路追踪实战 》

Edgar

Edgar
一个略懂Java的小菜比