SaaS 应用的可观测性设计

引言

对于分布式系统,由于其远超传统软件的系统复杂性,系统运维的难度大大增加,且会随着分布式节点的增加而指数级增长。当系统出现故障时,要在数以千百计的应用节点中找出问题所在,对于开发人员来说,是一个巨大的挑战。尤其是很多节点的指标都异常时,何为因,何为果,往往难以辨别。

而另一方面,对于 SaaS 应用来说,其面向企业的属性,决定了对于服务可靠性的极高要求。一是出现故障时,我们需要快速定位问题并排除故障,恢复服务。更重要的,则是能够时刻清楚了解系统的运行状态,在系统有变坏趋势发生前,及时发现,消灭故障于无形。

要做到这些,最基础,又最重要的,便是系统具有极高的可观测性。

什么是可观测性

当我们开着一辆汽车行驶在路上时,仪表盘上的码表,转速表,油量计等仪表指示了汽车当前的基础运行状态。当有黄色指示灯亮起时,表示车辆对应的某个零件有隐患,需要检查,但还不至于影响车辆的基本运行和安全功能。而当有红色指示灯亮起时,则是严重警告,最好立即把车送去检查维修,否则车辆核心部件可能受损,或者存在严重安全隐患,容易引发事故。

某汽车品牌仪表盘

汽车仪表盘及其连接的传感器和信号传输系统,便是对于汽车系统可观测性的最基础,最直观的例子。如果需要更深入了解汽车各个部件的状态,还可以连接车辆的 OBD 接口,从中获取到更多的车辆当前状态以及历史状态数据。通过 OBD 接口,汽车系统的可观测性也被大大增强。基于 OBD 数据,又衍生出了很多的手机管理软件,可以更简单的观察车辆状态,还能记录过往更多历史数据,做驾驶习惯趋势分析等,更大的扩展了汽车的可观测性。

在 IT 领域,可观测性的重要性有过之而无不及。CNCF(云原生计算基金会)对于 Cloud Native 的定义中,就包含 observable 这一重要特征。从汽车的例子,可以简单归纳出可观测性的定义,即能够将系统的内在状态,通过采集,分析,处理后,通过合理的聚合,归纳,展示指标数据,让人可以在最短时间内了解到系统发生的一切

具备可观测性的系统,运维以及研发人员可以直观的观察到系统的整体运行状态是否健康,同时又能轻易的深入到运行的各个细节角落。在正常运行时,观测系统能对系统负载进行评估,对运维操作提供建议。在发生故障时,可协助快速定位和修复问题。在运维自动化和智能化的大趋势中,系统的可观测性是其中最基础的一环

构建完善的观测系统

系统可观测性的能力主要是由一个完善的监控系统提供。市面上有很多开源的分布式监控系统,比如 Prometheus,Zabbix,nagios,CAT 等。其中,Prometheus 更已成为事实上的接口标准。而各个大公司出于灵活,定制以及强大的运维开发能力,会有自己的监控系统。无论哪种监控系统,其构成组件是基本一样的,下面是 Prometheus 的架构图:

图片引自 Prometheus 官网

从图中可以看到,一个系统具备可观测性,必须具备以下这些组件:

1.服务状态感知组件

在系统的各个节点,以全面的维度,采集服务状态信息,提供原始数据。由于采集的数据量巨大,该组件又直接部署在系统的运行节点上,需要使用各种方式来避免对系统正常运行造成影响。感知组件通过多种方式来采集状态数据,然后按照标准接口输出结构化的数据。常用的采集方式包括:

  • 独立监测工具,例如,监测系统运行状态的 sar,top,dstat 等。
  • 字节码注入
  • 结构化日志
  • 行为事件埋点

2.状态数据搜集和存储

该组件是整个观测体系的核心,将采集的数据上报,然后高效的存储下来。对于不同的数据,不同的分析方式,应采用合适的存储数据格式和存储介质。最常用于存储监控数据的是时序数据库,例如 Prometheus,InfluxDB 等。对于数据采集方,提供各种度量类型,用于结构化的汇报数据,包括

  • Gauges:计量器,用于内存,线程数等简单计数场景。
  • Counters:计数器,用于请求数,错误数等统计场景。
  • Histograms:直方图,用于平均响应时间,RT 95 值等需要计算均值,方差,分位数的场景。
  • Meters:TPS计数器,用于速率统计,以及 1 分钟,5 分钟均值一类的统计。
  • Timers:计时器,用于统计请求时延,例如请求时延,磁盘读取时延等。

3.可视化展示

观测系统能否产生价值,可视化界面是最主要的一个决定因素,可视化系统必须支持灵活配置,灵活组合,又易于使用,信息展示足够直观。开源的可视化监控工具使用最广泛的是 Grafana。

4. 报警

报警功能是整个监控系统最核心的价值之一,在系统已经发生异常或者可能会发生异常时,报警系统能通过邮件,IM,短信,电话等多种渠道,及时通知到相关方,让相关的运维和研发介入处理。

IM通道报警示例

报警配置主要有两类,状态事件报警和趋势报警。

状态事件是指已经发生的异常事件,例如:

  • CPU 使用率超过 95%
  • 磁盘空间占用率超过 90%
  • JVM 连续发生 fullgc
  • 接口调用一段时间失败超过 N 次,比率超过 x%
  • Tomcat 线程数超过 120
  • 业务打印出 ERROR 级别日志

趋势报警是指对指标变化趋势进行分析,然后对异常变化进行报警处理,例如:

  • 消息量比一周前下降 30%
  • 某 URL 接口请求量比一分钟前增加了 30%
  • 内存使用量连续十分钟增长超过 5%

覆盖全面的观测维度

(一)资源监控

资源主要是指系统计算资源和网络带宽资源,常见的有 CPU,内存,磁盘 ID,网卡流量等。这类指标通常是以数值,百分比等方式进行统计,用于直观的衡量系统负载情况。作为最基础的监控项目,各种类型的开源监控系统和云计算平台都有提供。

资源情况监控示例

对于各个类型的资源,下面是一些经常要关注的点,要在我们的监控系统中清晰呈现出来。

  1. CPU:对于计算型应用,CPU 是核心资源,负载高低直接指示了当前的系统的负载情况。对于非计算型应用,CPU 通常处于低负载状态,如果某个时间点 CPU 负载突然飙高,通常指示应用有 bug 了,比如有死循环,或者是虚拟机在频繁的 fullgc 导致负载下不来,或者是网络流量飙高导致 CPU IO 处理以及上下文切换负担加重。
  2. 进程存活情况:检查是否存在指定进程名的进程。
  3. 内存:内存使用率,剩余内存量。
  4. 硬盘:包括硬盘空间,inode 数量,磁盘 IO 情况等。
  5. 网卡:进出网络流量,进出网络 PPS,丢包率等

(二)性能监控

资源监控聚焦于操作系统层面,性能监控则聚焦于应用层面,也就是我们常说的应用性能管理(APM)

对于应用进程层面的监控,通常通过在虚拟机层,或者字节码执行层通过隐式注入的方式,来获取监控指标数据,常见的像 JVM,PHP 的 Zend Engine 等。以 Java 应用为例,通过这种方式,我们可以获取到的监控指标有:

  • JVM 内存状态
  • JVM GC 情况
  • Java 方法调用统计
  • Tomcat 线程状态
  • 自定义线程池工作状态

而在接口层面,对于传统的应用程序,仍旧可以通过字节码注入的方式来获取。对于云原生的应用,则可以通过 sidecar 的方式来监控。通过监控,我们可以获取到接口的 QPS,并发调用量,响应时间分布,错误次数等各个指标。

http 接口调用情况监控示例

能通过这种方式来监控的接口类型有:

  • HTTP 接口调用/被调用情况统计
  • RPC 接口调用/被调用情况统计
  • SQL 执行情况统计
  • Redis 访问情况统计

单节点的接口性能只能体现一个节点的情况,意义还不是那么大。但当把整个平台所有服务的接口调用情况串起来之后,就可以对系统全貌运行情况有直观的展示,这就是当下比较火热的调用链路追踪系统。当前主流的调用链路追踪系统的理论基础基本上都是 Google 的 Dapper,流行的开源组件有:Zipkin,Pinpoint,SkyWalking 等。通过调用链路追踪,我们可以轻易做到:

  • 各个服务节点性能分析
  • 故障快速定位
  • 请求调用链路分析
  • 服务依赖分析与治理

七鱼全链路监控大盘

(三)业务监控

不论何时,业务表现才是最直接的关切点,最直接的监控也就是业务监控。常见的业务监控就是各种业务大盘,比如淘宝双11 的交易数据大屏,这类大屏数据通常用于对外展示,或者给领导看,外观都会设计的很酷炫,展示的数据类型上也会经过一些筛选。

而对于研发团队,业务监控最重要的是指示业务的健康程度,因此展示的数据类型会所有不同,一般会更加细致,维度也会更加全面。

首先,对业务整体状态有监控。整体监控主要关注核心业务的健康度,保证核心业务有任何异常时,可以即时提醒。

七鱼部分业务监控面板

比如,对于七鱼来说,其核心业务流程是访客与客服的沟通,以及客服工作效率提升,因此整体业务监控指标会包括:

  • 并发会话量
  • 并发话务量
  • AI 解答量
  • AI 解决率
  • 在线坐席数
  • 消息收发速率
  • 工单创建速率

然而,整体业务趋势没有明显异常,但在某一个细分的维度下,可能业务已经完全不可用了。因此在整体业务之下,监控还要继续下钻,从各个不同的维度进行监控。常见的细分维度有:

  • 地域:地域主要关注的是网络情况,尤其是对于视频这种网络敏感的业务。网络地域差异最大的是 CDN 覆盖质量,其次是各地域运营商对于网络访问的限制措施,再就是经常见诸报道的某个地方的光纤被挖断的事件。
  • 用户:对于不同类型的用户,可能会提供不同的功能,常见区分用户的方式有 VIP,标签等等。

(四)租户状态跟踪

对于 SaaS 业务,提供服务是以租户为粒度的。为了提供个性化的服务,租户有很大可自由定制的功能。同一个功能,在一个租户是正常工作的,但在另一租户那里,可能就已经完全不可用了。因此,还需要分租户维度对业务主体功能进行监控。对客户的状态跟踪分为两部分,一部分是 SaaS 平台功能,另一部分是客户的接口监控。

SaaS 平台功能容易理解,是指由 SaaS 平台给各个客户提供的功能服务,对客户,特别是大客户以及新客户的功能使用情况进行持续跟踪有很重要的意义。首先,企业客户对于服务的稳定性要求很高,一旦出现任何异常,即使是非常微小,但只要被客户感知到,就很可能会影响客情关系,甚至引发投诉,影响后续的续费及增购。其次,功能使用量的变化可以反映客户对于平台的依赖程度,当客户某个功能使用量突然降低,或持续降低时,应关注客户的业务是不是有收缩,或者是不是客户一部分业务已经迁移到了竞品,此时要及时了解原因,维护好客情关系。如果某个功能突然被客户大量使用,则可以开始为客户即将到来的增购做好准备了。

重点企业消息接口监控面板

另一部分是客户自己的接口。SaaS 平台提供的功能中,很多都会涉及到客户自己的业务数据,需要和客户自己的系统做打通,因此 SaaS 通常会提供很多接口标准,由客户实现,然后 SaaS 平台在业务流程中去调用。这些外部接口不受平台控制,提供的服务质量参差不齐,出现异常的概率也很大。虽然这些接口故障不影响 SaaS 平台的整体服务,但一来对具体的客户则可能是灾难性的,二来出现故障后客户的第一反应通常是 SaaS 平台的故障,要求你尽快查清,这会浪费团队相当多的时间。客户也不一定有那么完善的监控措施,所以,我们必须把这些接口调用情况按照租户维度监控起来,在出现异常时及时通知到客户,既是对客户负责,也是减轻自身的工作压力

(五)业务日志

日志是事后分析的主要手段。完善的日志信息,可以产生下面这些重要价值:

  • 业务结果不符合预期时,可以业务调用链路信息进行完整复原分析,找到问题的原因。
  • 对 ERROR 级别日志以及特定关键字的日志进行监控报警。
  • 通过结构化的日志,统计分析调用量,执行结果等信息,辅助运营数据统计。

为了这些价值,使用日志系统有一些最佳实践可以遵循。

首先,良好的日志内容应该是记录的信息不多不少刚刚好的。记录信息太少的问题很明显,但是太多也同样会有问题,会导致真正有用的信息被稀释,增加整个日志系统的负担,甚至影响到核心业务的性能。

展开阅读全文

本文系作者在时代Java发表,未经许可,不得转载。

如有侵权,请联系nowjava@qq.com删除。

编辑于

关注时代Java

关注时代Java