监控分析:你的性能调优工具足够有效吗?

目前业界较为常用的观测技术手段,主要包含四种,即计数器、跟踪、剖析和监视。

计数器是对特定事件的一种统计方式,它是一种成本极低的观测手段,因此通常可以一直开启以监测特定事件的发生次数。在操作系统级别和硬件级别有许多计数器可供使用。例如,可以使用命令 “iostat” 来获取与输入 / 输出(IO)相关的统计信息,具体如下所示。

首先,来了解一下业界常用的观测技术手段。主要有四种,分别是计数器、跟踪、剖析和监视。

计数器:这是针对特定事件的一种统计手段,成本非常低,通常可以一直开启以监测特定事件发生的次数。在操作系统级别和硬件级别有很多计数器可用,比如使用命令 “iostat” 可获取与 IO 相关的统计信息。

跟踪:通过收集一系列操作或事件内容来跟踪分析业务流程的观测手段,日志打印就是一种跟踪手段。不过跟踪一般存在一定开销,不建议全部开启。以高性能软件系统为例,一般只有错误或告警级别才会默认开启日志打印。

剖析:通过对目标进行采样或者快照来归纳目标特征的观测手段。但受采样周期影响,往往存在采样反馈特征不准确或有偏差的问题。所以一般只有在分析软件代码函数调用栈概率分布时才会使用这种方式。例如,使用 JProfile 分析 Java 程序的热点代码就是采用这种方式。

监视:这是一种主动触发控制的观测手段,通过显式触发获取特定周期内的信息,以支持监控数据获取的过程。比如操作系统级别的 Sar 命令等。

对于操作系统内核和硬件来说,已有很多基于这四种观测手段开发的监控工具,可实现对其内部进行深入的性能监控分析。比如使用 iostat 命令获取 IO 统计、使用 top 命令获取进程使用统计等。

然而,对于实际开发的软件系统来说,仅仅基于操作系统内核和硬件级的监控观察手段,来分析复杂的业务性能问题还远远不够。

我举个例子。假设你的公司研发了一个演唱会购票交易网站,由于某个演唱会极为火热,在卖票期间出现整个网页卡死的性能问题。为了更好地监控分析这个性能问题,就需要在业务中增添许多观测手段,例如获取网页在线人数、同时提交购票请求人数、购票交易平均时长等众多观测数据,以协助进行性能分析。

如此一来,为了更深入地对业务性能进行监控分析,还需要在实际软件系统的开发过程中,单独定制化实现以上不同种类的观测手段。不仅如此,因为软件系统都是运行在操作系统(OS)和具体硬件芯片之上,所以对于一些复杂的业务性能问题,需要统筹好操作系统与软硬件定制开发的观测手段,共同配合,这样才能更有效地支撑性能问题的分析定位。

然而,要想实现以上目标,就需要我们对软件系统的性能监控观测节点和观测手段有全面的了解和把握。所以接下来,我们通过一个通用的软件系统观测视图,来了解如何才能更有效地支撑性能问题的监控分析工作。

实际软件系统的观测节点和手段都有哪些?

现在的软件系统通常都不是单机系统,而是一个复杂的分布式系统或是云服务化产品。所以,针对软件系统的监控分析就不再会停留在单机上,而是需要对系统中很多的节点和元素进行观测。

下面展示的是一个软件产品或服务的系统观测视图,你可以认为图中的每一个矩形元素都是一个观测节点,它们都提供了前面四种观测手段中的一种或者几种观测手段。

那么在这个系统观测视图中,你可以发现上层的软件与服务是运行在下层的软硬件之上的,因此我们针对下层软硬件的监控分析,其实也可以支撑上层服务和组件的性能分析。

硬件层的 CPU:

首先,在硬件芯片层,每个物理设备都有相应的观测方式。以 CPU 芯片为例,如今的 CPU 芯片架构愈发复杂,如何写出对 CPU 更加友好的代码,充分发挥 CPU 的硬件性能,成为一个重要的性能调优方向。

就 CPU 观测分析来说,现在的大多数 CPU 都设有性能监控单元(Performance Monitoring Unit, PMU),能够统计系统中发生的特定硬件事件,比如缓存未命中(Cache Miss)或者分支预测错误(Branch Misprediction)等。因此,可以利用这些观测数据进行分析,并指导优化软件的编码实现,以提升在 CPU 芯片上的执行效率。

以 Intel 的 CPU 体系架构为例,其内置的计数器有几百个。可以使用工具 perf 获取这些计数器的值,再借助工具如 pmu-tools、intel-Vtune profile,并使用 TMAM(Top-down Microarchitecture Analysis Method,自顶向下的微架构分析方法),分析出取指令阻塞、取数据阻塞、指令分支预测效率低等影响 CPU 性能发挥的因素,从而指导编码优化来提升 CPU 的 IPC(单周期的执行指令数),进而提升软件的性能。

在芯片之上是操作系统内核层,其中包含进程、协议栈、文件系统等功能。而每个功能都有相应的观测工具与手段。

以进程为例,我们能够通过 “ps”“pmap” 等命令来获取内存和 CPU 使用的统计信息,也可以借助 “strace” 等命令获取系统调用的跟踪信息。

云平台:

如今,我们的软件系统通常并非只在一个单独的操作系统内核上运行,而往往是在一个云平台上运行。对于互联网应用与服务产品来说,这个平台通常指的是 PaaS 平台。各大云厂商如 AWS、阿里云、Azure 等都提供了研发 PaaS 云平台,当然你也可以使用 Kubernetes 来组建一个私有的 PaaS 云平台。

但是,不管选择使用哪一款 PaaS 平台,它们实际上都提供了对应的监控运维工具,可以支持获取平台上的弹性资源、负载均衡等相关的监控观测数据。

公共服务:

另外,对于软件系统来说,通常会依赖很多公共服务,常见的有数据库、消息队列或其他第三方服务等。这些公共软件与服务一般都有相应的观测与监控分析工具。以数据库 MongoDB 为例,有基于统计的观测工具 “mongostat”,还可以使用 “Profiler” 进行查询分析,也有专业监控分析工具 “MMS(MongoDB Monitoring Service)” 等。

软件系统架构中的服务 / 组件:

在操作系统与云平台之上是软件系统架构,软件系统架构由众多服务或组件组成。首先,这些服务与组件通常能够获取线程使用、内存使用、CPU 使用、IO 使用等与底层相关的监控观察数据,不过由于运行虚拟机和编程语言的差异,可选择的工具不同。例如,在 C/C++ 语言中,常用的剖析分析工具包括 gperftools、gprof、Valgrind 等;对于 Java 语言,常用的剖析分析工具有 VisualVM、JProfiler 等。其次,这些组件与服务还需根据特定的业务场景,开发实现一些自定义的观察手段或工具,以支持从业务视角进行性能分析。比如增加业务相关的计数器统计,或者添加动态 Trace 机制等。实际上,这部分的观察手段与能力是很多业务性能问题分析的关键,所以需要重点考虑并建设。

再进一步,云平台、软件系统、公共服务共同协作实现了整个产品的业务功能。对于一个复杂的业务系统而言,也应该有相应的观测分析工具。所以,很多大型业务系统通常在后台管理工具中集成了各种观测数据分析工具,这样就能比较方便地进行性能问题分析和调优。但对于一些不成熟的软件系统,其提供的观测分析手段可能比较薄弱,从而导致对软件系统进行性能调优非常困难。

根据以上介绍分析可以发现,对于一个业务软件系统来说,从上到下的可观测节点数目非常多,而且每个观测节点提供的观测分析工具种类也很多。在对软件系统的性能进行监控分析时,寻找定位到待观测分析的节点,并使用对应的观测分析工具获取监控数据的过程通常非常耗时。从我的实践经验来看,很多研发人员在进行性能调优时,绝大部分时间都花在了学习和选择观测分析工具上,效率非常低。

如何构筑软件系统观测工具体系?

首先,为了更好地使用观察工具来支撑对系统的性能调优,我们应该从种类繁多的监控工具中解脱出来,尽量使用统一的监控平台与工具来支撑性能调优。如下图右侧所示,我们可以尽量将系统中的观察分析数据对接到统一的分析平台上,来减少寻找使用各种工具的成本。

通常情况下,各种云厂商提供的 PaaS 平台都自带监控运维工具,并且自动集成了操作系统层、硬件层常用的观测数据,所以很多时候,你无需深入了解具体观测工具的使用方法。其次,根据业务中性能调优的需求,可以将软件组件与服务、业务层、公共服务层等相关的观察数据,通过各种适配器和服务对接至统一的 PaaS 监控运维工具中。这样做的好处在于能够将不同系统服务间获取的监控数据关联起来进行分析,从而更好地支撑性能问题的分析与定位。

在我以前参与的一个性能优化项目中,产品部署在 AWS 上。为了更好地支撑性能优化,我们首先将 ClickHouse、MongoDB 等重要观察数据注入到统一的 PaaS 监控数据分析平台中。这样,当出现性能问题时,仅需基于这个 PaaS 平台上的监控数据,就可以初步确定性能问题发生在哪个服务或组件上。

如果在你参与的项目案例中,没有这个 PaaS 数据分析平台,或者平台能力不成熟,你也可以基于相关的开源技术来构建这部分工具能力。例如,使用 Elasticsearch 和 Kibana 来记录跟踪业务处理日志或组件与服务间的交互日志;或者使用 Prometheus 和 Grafana 来记录系统中相关的计数器事件等。实际上,很多时候在进行系统调优的过程中,也是构筑系统级监控分析工具的最佳时机。如果我们将这部分能力集成和沉淀下来,就可以提升后续性能调优的分析工作效率。


请使用浏览器的分享功能分享到微信等