当前位置: 首页 > 科技观察

系统和应用监控的一丝不苟堪称性能瓶颈的克星

时间:2023-03-20 17:24:04 科技观察

1、在实际的性能分析中,一个很普遍的现象就是明明出现了性能瓶颈,但是当你登陆服务器想在调查过程中,发现瓶颈已经消失。也就是说,性能问题总是时有发生,但很难找出发生的规律,也很难重现。为了解决这个问题,需要建立一个监控系统来监控系统和应用程序的运行状态,并定义一系列的策略,以便在出现问题时第一时间发出警报和通知。一个好的监控系统,不仅可以实时暴露系统中的各种问题,还可以根据监控到的状态,自动分析定位瓶颈的大致来源,从而更准确地将问题反馈给相关团队。做好监测,核心是全面的、可量化的指标,既包括系统方面,也包括应用方面。从系统的角度来看,监控系统应该涵盖系统整体的资源使用情况,比如我们前面提到的CPU、内存、磁盘和文件系统、网络等系统资源。从应用程序的角度来看,监控系统应该涵盖应用程序内部的运行状态,这不仅包括进程的CPU和磁盘I/O的整体运行状态,还需要包括诸如时间-消耗接口调用、执行过程中的错误、内部应用程序的内部健康状况,例如对象的内存使用情况。二、系统监控1、USE方法在开始监控系统之前,你一定想知道如何用一种简洁的方法来描述系统资源的使用情况。当然,你可以使用专栏中学习到的各种性能工具,分别收集各种资源的使用情况。但不要忘记,每种资源都有很多性能指标。且不说使用过多的指标费时费力,要为您建立系统的整体运行状态也并非易事。这里给大家介绍一种专门用于性能监控的USE(UtilizationSaturationandErrors)方法。USE方法将系统资源的性能指标简化为三类,即利用率、饱和度和错误数。利用率,表示资源用于服务的时间或容量的百分比。利用率为100%,表示容量已经耗尽或一直在使用服务。饱和度表示资源的繁忙程度,通常与等待队列的长度有关。100%饱和意味着资源不能接受更多的请求。错误数表示发生错误的事件数。错误数越多表示系统问题越严重。这三类指标涵盖了常见的系统资源性能瓶颈,因此常用来快速定位系统资源性能瓶颈。这样一来,无论是CPU、内存、磁盘、文件系统、网络等硬件资源,还是文件描述符数、连接数、连接跟踪号等软件资源,USE方法都可以快速帮助你找到它是哪一个。系统资源出现性能瓶颈。2.性能指标那么,对于每一种系统资源,有哪些共同的性能指标呢?回顾我们讲过的各种系统资源的原理,不难想到相关的性能指标。在这里,我把常用的性能指标画了一张表,方便大家需要的时候查看。但需要注意的是,USE方法只关注能够反映系统资源性能瓶颈的核心指标,但这并不意味着其他指标不重要。还需要监视各种其他指标,例如系统日志、进程资源使用情况和缓存使用情况。但是,它们通常用作辅助性能分析,而USE方法的指标直接指示系统的资源瓶颈。3、监控系统掌握了USE方法和需要监控的性能指标后,接下来要做的就是建立监控系统,保存这些指标;然后根据监控的状态,自动分析定位大概的瓶颈源;最后通过报警系统将问题及时报告给相关团队。可见,一个完整的监控系统通常由数据采集、数据存储、数据查询与处理、报警和可视化显示等多个模块组成。因此,从零开始搭建监控系统其实是一个很大的系统工程。不过好在有很多开源监控工具可以直接使用,比如最常见的Zabbix、Nagios、Prometheus等。下面,我就以Prometheus为例,为大家介绍一下这些组件的基本原理。如下图所示,是Prometheus的基本结构:(图片来自prometheus.io)首先看数据采集模块。最左边的Prometheustargets就是数据采集的对象,Retrieval负责采集这些数据。从图中也可以看出Prometheus支持Push和Pull两种数据采集方式。在Pull模式下,获取是由server端的获取模块触发的。只要采集目标提供HTTP接口,就可以自由访问(这也是最常用的采集方式)。在Push模式下,每个采集目标主动将指标推送到PushGateway(用于防止数据丢失),然后服务器端从Gateway中拉取(这是移动应用中最常用的采集模式)。二是数据存储模块。为了维护监控数据的持久化,图中的TSDB(Timeseriesdatabase)模块负责将采集到的数据持久化到SSD等磁盘设备中。TSDB是专门为时序数据设计的数据库。其特点是以时间为索引,数据量大,以追加方式写入。三是数据查询与处理模块。刚才说的TSDB,在存储数据的同时,实际上提供了数据查询和基本的数据处理功能,这就是PromQL语言。PromQL提供简洁的查询和过滤功能,支持基本的数据处理方式,是报警系统和可视化展示的基础。第四个是报警模块。右上角的AlertManager提供告警功能,包括基于PromQL语言的触发条件、告警规则的配置管理、告警发送。不过,虽然警告是必要的,但过于频繁的警告显然不可取。因此,AlertManager也支持分组、抑制或静默,聚合相似的告警,减少告警数量。最后一个是视觉显示模块。Prometheus的webUI提供了一个简单的可视化界面来执行PromQL查询语句,但是结果的展示比较单调。但是,一旦使用了Grafana,就可以构建出非常强大的图形界面。介绍完这些组件之后,想必大家对每个模块都有一个比较清晰的认识。接下来,让我们继续详细了解这些组件组合起来的整体功能。例如,以刚刚提到的USE方法为例,我使用Prometheus采集Linux服务器的CPU、内存、磁盘、网络等资源的利用率、饱和度和错误计数指标。然后,通过Grafana和PromQL的查询语句,可以直观的以图形化的界面展现出来。4.最后得出系统监控的核心是资源使用情况,包括CPU、内存、磁盘、文件系统、网络等硬件资源,以及文件描述符数量、连接数、和连接跟踪。要描述这些资源瓶颈,最简单有效的方法就是USE方法。USE方法将系统资源的性能指标简化为三类:利用率、饱和度和错误。当这三类中的任何一类指标过高时,都意味着对应的系统资源可能存在性能瓶颈。基于USE方法建立性能指标后,我们需要使用一个完整的监控系统,将这些指标从采集、存储、查询、处理,到告警和可视化展示整合起来。这样不仅可以快速暴露系统资源的瓶颈,还可以借助历史监控数据跟踪定位性能问题的根源。三、应用监控1、应用监控指标同系统监控。在构建应用监控系统之前,首先需要确定需要监控哪些指标。尤其要清楚您可以使用哪些指标来快速识别应用程序性能问题。应用的核心指标不再是资源的使用情况,而是请求数、错误率和响应时间。这些指标不仅直接关系到用户体验,也反映了应用程序的整体可用性和可靠性。通过请求数、错误率和响应时间这三个黄金指标,我们可以快速知道应用是否存在性能问题。但是,光有这些指标显然是不够的,因为出现性能问题后,我们也希望能够快速定位到“性能瓶颈区域”。因此,在我看来,监控应用时,以下指标也是必不可少的。第一个是应用进程的资源使用情况,比如进程占用的CPU、内存、磁盘I/O、网络等。使用过多的系统资源,导致应用程序响应缓慢或错误计数高,是最常见的性能问题之一。其次是应用之间的调用,比如调用频率、错误次数、延迟等。由于应用不是孤立的,如果它所依赖的其他应用出现性能问题,应用本身的性能也会受到影响。三是应用内部核心逻辑的运行,比如关键环节的耗时,执行过程中的错误等。由于这是内部应用程序状态,因此通常无法直接从外部获得详细的性能数据。因此,在设计和开发应用程序时,应提供这些指标,以便监控系统了解其内部运行状况。借助应用进程的资源使用指标,可以将系统资源瓶颈与应用关联起来,从而快速定位系统资源不足导致的性能问题;通过应用间的调用指标,可以快速分析出在一个请求处理的调用链中,哪个组件是性能问题的罪魁祸首;而有了应用内部核心逻辑的运行性能,就可以更进一步,直接进入应用内部,定位是哪一个处理循环的Function导致了性能问题。基于这些想法,我相信你可以构建描述应用程序运行状态的性能指标。将这些指标融入到我们上一期提到的监控系统(比如Prometheus+Grafana)中,就可以和系统监控一样。一方面可以通过报警系统将问题及时报告给相关团队;另一方面,通过直观的图形界面动态显示应用程序的整体性能。2.全链路监控业务系统通常涉及一系列多个服务,形成复杂的分布式调用链。为了快速定位这类跨应用的性能瓶颈,还可以使用Zipkin、Jaeger、Pinpoint等各种开源工具搭建全链路追踪系统。例如,下图是Jaeger调用链跟踪的示例。(图片来自Jaeger文档)全链路跟踪可以帮助你在一个请求处理过程中快速定位到哪个环节是问题的根源。比如从上图可以很容易看出这是Redis超时导致的问题。全链路追踪除了可以帮助您快速定位跨应用的性能问题,还可以帮助您生成线上系统的调用拓扑图。这些直观的拓扑图在分析微服务等复杂系统时特别有效。3、日志监控性能指标的监控可以让你快速定位到瓶颈的位置,但是光有指标往往是不够的。比如对于同一个接口,当请求传入的参数不同时,可能会造成完全不同的性能问题。因此,除了指标之外,我们还需要监控这些指标的上下文信息,而日志就是这些上下文的最佳来源。相比之下,指标是特定时间段的数值测量数据,通常按时间序列处理,适用于实时监控。日志完全不同。日志是某个时间点的字符串消息。通常需要被搜索引擎收录后才能进行查询和汇总分析。对于日志监控,最经典的方法是使用ELK技术栈,它是Elasticsearch、Logstash和Kibana这三个组件的组合。如下图所示,是一张经典的ELK架构图:(图片来自elastic.co)Logstash负责从各种日志源收集日志,然后进行预处理,最后将初步处理后的日志发送给Elasticsearch进行索引。Elasticsearch负责对日志进行索引,并提供完善的全文搜索引擎,让您可以轻松地从日志中检索到您需要的数据。Kibana负责日志的可视化分析,包括日志搜索、处理、华丽的仪表盘展示。下图是一个Kibana仪表板示例,直观地显示了Apache的访问配置文件。(图片来自elastic.co)值得注意的是,ELK技术栈中的Logstash资源消耗比较大。因此,在资源受限的环境中,我们经常使用消耗资源较少的Fluentd来替代Logstash(即所谓的EFK技术栈)。4、最后,应用程序的监控可以概括为指标监控和日志监控两部分:指标监控主要是对一定时间内的性能指标进行度量,然后通过时间序列进行处理、存储和告警。日志监控可以提供更详细的上下文信息,这些信息通常通过ELK技术栈进行收集、索引和图形化展示。在跨多个不同应用的复杂业务场景中,还可以构建全链路跟踪系统。这样可以动态跟踪调用链中各个组件的性能,生成整个流程的调用拓扑图,从而加快复杂应用性能问题的定位。