性能调优方法论:如何科学高效地定位性能问题?

科技事要畅享 2024-08-29 16:02:59

一提起软件系统中的性能问题,或许你首先想到的是 CPU 使用率过高或者内存占用率太大,进而致使程序执行速度变慢。此时,关注点往往只停留在软件实现层面的性能调优上。实际上,这种以最小化资源占用为导向的性能优化,其核心目标是降低成本。

然而,对于产品来说,最为关键的其实是从客户视角所关注的业务性能,比如用户的平均响应时延、99% 的用户响应时延分布等。这类性能优化的核心目标是提升用户体验,增强产品的行业竞争力。

但问题在于,在互联网服务领域,从客户视角去定位分析业务的性能问题存在一定挑战,主要原因有两点:

针对一些存在业务性能问题的场景,其系统内的服务或组件并不一定处于饱和状态,所以无法直接从系统资源级监控中识别出问题。如果只是个别服务或组件处于饱和状态,往往可以通过弹性扩展来更快地提升性能体验,所以这种情况也不是最棘手的性能问题。

再来看看嵌入式领域,以无线通信领域为例,存在很多业务性能优化非常苛刻的场景,如 FTP 下载速率优化、速度平稳没有毛刺优化等。在这类系统的实现过程中,导致出现业务性能问题的原因会更多更复杂,问题可能发生在链路上的任何一个网元设备内,或者具体设备内的任何一个软件组件或硬件单元上。因此,定位分析业务层性能问题的挑战会更大。

事实上,定位分析业务的性能问题是很多程序员都很头疼的问题。它需要你具备很高的业务能力,包括对业务流程的熟悉度、对软件架构及软件内实现逻辑的理解程度,甚至是对操作系统和硬件原理都要有深入的理解。不过,就我的实践经验来看,即使掌握了这些信息,如果没有系统的定位分析方法的指导,依旧很难定位出性能问题。

所以,今天这节课我会给你分享一套性能调优方法论,带你理解企业应用系统架构的整体逻辑和工作流程,在此基础上了解引起性能问题的潜在软硬件瓶颈点,最后介绍系统分析定位的方法。基于这个方法,当你再碰到比较棘手的业务性能问题时,就可以做到有的放矢,使用这套系统定位分析方法去解决真实的性能问题。

好了,下面我们就来了解下系统的整体架构。

系统架构视图

为了能更好地分析与定位复杂的性能问题,你首先需要理解整个系统架构视图,其核心主要包含这三层:产品业务模型、软件系统架构、组件或服务实现,如下图中所示:

图片

产品业务模型:这是系统对外提供的业务功能与逻辑。以购物流程为例,其对外提供的功能逻辑为:浏览商品 —> 添加购物车 —> 查看库存 —> 支付 —> 发快递等。这实际上是站在用户视角所感知到的与系统发生交互的过程。这个业务模型是软件业务领域建模阶段的重要产物,也是每个系统级产品都应包含的模型。

软件系统架构:它表示的是整个软件系统到具体组件或服务之间的拆分逻辑,以及组件或服务间的交互关系,如图中的 A、B、C、E、F 等。这些软件运行单元可以是一个微服务实例,也可以是一个组件实例,它们会通过通信与交互支撑实现复杂的业务功能。实际上,不管是嵌入式领域还是互联网领域,软件系统架构设计本质上都是对业务功能拆解的一个过程,通过拆分形成具有独立清晰边界的、更小的软件运行单元。

组件或服务实现:这是组件或服务的内部代码实现,它会依托于进程、内核、硬件的协作来完成核心的业务功能。我们知道,系统的业务性能是由硬件、操作系统、软件实现以及之上的业务流程综合决定的。当我们碰到业务性能问题时,会基于系统的架构视图从上到下进行分析,最后总能找到具体的制约性能的瓶颈点。

那么,如果你可以提前认识软硬件中常见的一些性能瓶颈点,了解它们对系统性能的影响,就能够帮助你更加准确地分析业务性能问题。但是,很多程序员在定位性能问题时,喜欢只聚焦到某个点上持续优化,而这个点可能并不是性能瓶颈,所以最后很难有比较好的效果。那么,系统潜在的性能瓶颈点都有哪些呢?接下来,我们就一起来看看。

潜在的性能瓶颈点

首先,一般来说,性能瓶颈通常是由一些关键资源使用过度所引起的,并且不同资源使用到达瓶颈(饱和)状态对性能产生的影响和规律各不相同。在计算机系统中,每种硬件资源,如 CPU、Cache、内存、磁盘、网络接口、总线等,都有可能成为性能瓶颈。这是因为当硬件处理到达饱和状态时,会直接导致硬件上的软件运行性能下降,最终使得业务性能受到影响。

相比之下,软件实现所导致的性能问题及影响很容易被忽略。所以今天,我会重点介绍由于软件实现而引起业务性能问题的瓶颈点,以便在你分析业务性能问题的过程中,更好地识别和发现这些问题。

串行资源受限

第一类典型的瓶颈问题是串行资源(或互斥资源),这是一种可能触发业务性能问题的软件实现方式。下图为串行资源的扩展对性能影响的模型图,它展示了随着业务规模的扩大,对性能所造成的影响。

图片

如图中左侧所示,由于串行资源是有限的,随着业务请求量的增加,当资源使用饱和后,会导致请求处理吞吐量到达峰值后便无法再提升。同时,如图的右侧所示,当串行资源使用饱和后,平均处理时延也会因排队或者阻塞而不断拉长。在软件实现中,对性能影响较大的串行资源种类有很多,从粒度从小到大可以包括:互斥锁、并行设计中的串行部分、系统依赖的不可扩展的服务或接口等,它们都有着相似的影响。但需要注意的是,在业务场景中,还有不少资源数目是大于等于 2 的情况,比如线程池、数据库连接池、其他不能无限扩展的服务或接口。这种有限软件资源的场景,它们对性能的影响与串行资源对性能的影响较为类似,所以同样可以参考串行资源对性能影响的分析视图。

缓冲类资源消息溢出

第二种容易引发性能问题的软件实现是缓冲类资源,像缓冲区、消息队列、消息中间件等都归属于缓冲类资源。缓冲技术能够实现削峰填谷的机制,从而平滑上游和下游处理速度之间的差异。如下图所示,倘若缓冲区设置过小,当上游请求到达峰值时,可能会致使部分请求被阻塞或者丢弃,进而影响到业务性能。而如果缓冲区设置得越大,其实现削峰填谷的能力就会更强。

但如果缓冲区设置得过大,也会造成内存资源的浪费,所以缓冲区大小设置对性能的影响也很关键。

缓存命中率过低

缓存技术在软件实现层面是一项重要的性能优化手段,同时也可能成为影响业务性能的潜在因素。我们了解到,在缓存的使用中有一个关键指标,即缓存命中率,其计算公式为缓存命中个数除以(缓存命中个数与缓存未命中个数之和)。这个指标对业务性能的影响如下图所示

图片

软件 Bug

最后,软件实现中存在一个对性能有着极大影响的因素 —— 软件 Bug。在以往对业务性能问题进行定位分析的过程中,由软件 Bug 导致的性能问题并不在少数。例如,代码本应是批处理操作,却因处理错误退化为循环调用;又或者在运用缓存技术时,由于缓存 Key 构造错误,使得缓存永远无法命中,进而引发业务性能骤然下降等情况。

然而,看到这里,你或许会产生疑问:是不是所有的业务性能问题都是由软硬件层面的资源性能瓶颈所触发的呢?在我看来,并非如此。有些性能问题可能源于业务模型或者流程本身的问题,软件和硬件仅仅是其载体。例如,业务中的某些限速策略会致使处理性能受到限制。另外,在一些更为复杂的系统业务设计中,也可能会引入性能问题,这就如同设计不合理的十字路口红绿灯一般,会导致严重的拥堵状况。不过,对于这种因业务模型等因素引发的性能问题,我们其实可以通过调整红绿灯时间,也就是调整软件不同模块的业务职责和接口实现,从而显著改善拥堵现象。

总而言之,在软件实现的过程中,可能引发潜在性能问题的因素众多。鉴于此,我们需要系统的分析定位方法作为指导,否则将很难准确识别出系统中的所有性能瓶颈点。

所以接下来,我们就一起探讨下这个系统分析定位方法吧。

系统分析定位法

实际上,用于分析定位性能问题的方法有不少。像 USE 方法,也就是从检查各类资源、观察其使用率饱和的角度去探寻可能存在的性能瓶颈;还有从下往上逐步分析系统中资源使用指标的方法来查找性能瓶颈。另外,还有随机变动讹方法(这是一种先随机猜测再进行验证的方法)、科学实验法等等。当面对特定的性能问题时,或许每种定位分析方法的效果都不一样。不过呢,今天我要向你介绍的这种方法,是我依据以往分析各类性能问题所积累的经验总结出来的一种方法思路。它相对比较系统,而且效率较高,当你在遭遇各种业务领域的性能问题时,都可以运用这种方法。具体如下图所示。

图片

整个定位分析方法从上到下分为三层,分别是业务模型分析、软件架构分析以及组件或服务实现分析。下面逐一为你介绍。

一、业务模型分析

业务模型分析的目标是找出引发业务性能问题的业务触发点,并对分析的正确性进行验证。越是复杂的业务模型,导致业务性能问题出现的根本原因可能就越难以察觉。如果在业务模型分析中确定的根本原因不准确,那么后续投入再多精力进行深入分析也将是徒劳无功。例如,在分析 TCP 流量下降的性能问题时,可能是下行链路出了问题,也可能是上行链路存在问题。如果上行链路延迟增大,导致 ACK 反馈不及时,进而触发拥塞控制,使得 TCP 流量不高。在这种情况下,即便在下行链路上花费巨大精力去分析,也不会有任何效果。所以,验证业务层性能问题根因分析的结论是否正确十分必要。在此,我建议你可以通过打桩的方式暂时规避根因触发点,观察性能问题是否有所改善,以此作为有效的验证手段。当然,不同系统的业务模型差异很大,所以业务模型没有通用的方法或规律可循,你只能凭借对业务逻辑的深入理解,并依据业务层实现的运行状态监控信息来进行分析。当完成业务模型分析后,你会发现导致性能问题的原因可能是由某个具体的业务流程引起的。这时,你就可以针对这个具体业务流程,深入到软件架构中进一步分析。

二、软件架构分析

在软件架构分析中,我们主要依靠软件架构中组件或服务的接口交互关系来进行分析。通常对于大型的系统级产品来说,组件或服务间接口的交互信息一定是可以被监控、获取并进行分析的。这样,根据获取的接口交互监控信息,我们能够找到触发业务性能问题的具体组件或服务。此外,和业务模型分析一样,我们在软件架构分析阶段识别出的存在性能瓶颈的组件或服务,也需要进一步验证。只有在确保分析结果正确后,才能进行下一阶段的深入分析。我以前在通信领域从事性能问题分析时,每个子系统组件都是由不同的团队开发维护的。当面对复杂的业务性能问题时,我需要沿着子系统组件的接口边界逐步排查分析,将性能问题交接给下一个子系统组件,并提供充足的分析与验证信息。但即使在这样的情况下,仍然可能出现分析错误导致返工的情况。所以这一点你一定要注意。

三、软件内部分析

事实上,在互联网业务领域分析性能问题时,无论是业务模型分析阶段还是软件架构分析阶段,验证分析结论正确性的过程都很容易被我们忽视,从而导致性能问题分析定位出现返工或错误。根据我的实践经验,当定位到具体的某个组件存在性能瓶颈时,我们就需要深入到这个组件内部去分析其具体实现,查看这个组件是否存在之前提到的性能瓶颈点,比如串行资源、缓存、软件 Bug 等,并根据分析结果给出优化建议。最后,当所有的性能瓶颈点都被解决后,你还需要再次验证性能问题是否得到改善。如果没有改善,那么你可能需要重新审视分析过程,或者寻找其他可能的性能瓶颈点。

如何在真实的数据分析业务中应用这套方法论?

这是我曾经处理在线数据分析业务中碰到的真实性能问题,当时产品有部分用户投诉,在 Web 页面中的查询数据下载功能性能很差,造成用户等待时间长。而我采用的就是这套性能定位方法,具体定位过程如下图所示:

图片

第一阶段:进行业务模型分析,以识别出存在性能问题的业务流程。在互联网服务领域,许多业务的性能问题是由用户发现的,然而在其他业务领域中,业务性能瓶颈点则需要依靠业务领域的监控统计,并结合业务模型共同分析才能识别出来。就这个案例而言,系统中可能包含众多的业务流程。在业务模型分析阶段,我们确定了存在性能问题的业务流程为 “查询数据下载功能”。具体的用户业务流程是:先选择查询条件,接着查询返回数据,然后生成压缩数据,再上传至对象存储,最后生成下载链接。之后,我们便可以依据这个业务流程,去寻找并定位那些引入性能瓶颈的组件和服务。

第二阶段:处于软件架构分析阶段时,我们能够根据存在性能问题的业务流程,找到由软件导致性能瓶颈的组件和服务。在这个阶段,主要运用系统的微服务间的接口日志进行分析,主要基于 Elasticsearch+Kibana 工具,沿着业务请求接口链路去寻找具体的组件或者服务,最终将性能问题定位到一个确定的微服务组件中。

第三阶段:进行组件或服务内实现分析。在此阶段,深入到导致性能问题的微服务中,通过查看内部实现的相关监控或统计信息,发现导致性能问题的原因是:压缩数据处理与浏览统计逻辑使用了相同的计算任务队列。由于之前的突发浏览业务,使得队列中积攒了许多待处理的浏览统计任务,进而导致压缩数据处理任务被排队阻塞,时延变长。这样一来,经过仔细分析后我们会发现,因为用户无法感知到浏览统计逻辑,而压缩数据处理对用户来说却比较敏感,所以在这里使用同一个任务队列,就造成了非关键业务逻辑对核心业务的处理时延产生了影响。

更多资讯,点击

0 阅读:0

科技事要畅享

简介:感谢大家的关注