当前位置:首页 > 科技  > 软件

线程剖析 - 助力定位代码层面高耗时问题

来源: 责编: 时间:2023-11-16 09:39:55 365观看
导读在当今的软件开发领域,性能问题是一个永不过时的挑战。为了解决这一挑战,开发人员需要深入了解他们的应用程序运行时的性能,并快速定位高耗时问题。线程剖析是一种强大的工具,通过采集和计算运行时线程栈,可以帮助开发人员

在当今的软件开发领域,性能问题是一个永不过时的挑战。为了解决这一挑战,开发人员需要深入了解他们的应用程序运行时的性能,并快速定位高耗时问题。线程剖析是一种强大的工具,通过采集和计算运行时线程栈,可以帮助开发人员更好地理解和解决性能问题。本文将深入探讨线程剖析的基本思想和实现思路,以及客户端和服务端的设计。lxR28资讯网——每日最新资讯28at.com

一、基本思想

线程剖析的核心思想是在业务线程执行请求时创建一个特定阈值触发的检测任务,用于监测高耗时问题。如果任务未被取消,在达到高耗时阈值时,将有专门的线程去执行剖析任务,采集业务线程的堆栈,并异步发送给剖析服务端进行计算,以估算出栈上的各个方法耗时。这个工具不仅提供了详细的性能数据,还能与开放遥测(OpenTelemetry)结合,从而实现链路特征的关联,主要流程如下:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

二、实现思路

客户端设计

客户端的架构主要体现在任务的创建、调度、执行和导出四个环节。lxR28资讯网——每日最新资讯28at.com

创建&调度任务

业务线程执行时,若满足指定要监控的接口或线程名称,将构造一个包含该线程对象的检测任务放入队列,时间轮的工作线程会周期性(默认100ms)在轮盘上移动一格,类似我们平时看到的钟表上的指针那样,每个周期会从任务队列取出所有任务,将各个任务分配添加到时间轮中每个格子中。如下图所示:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

执行任务

分配完成后,由任务执行线程池的线程去执行当前周期所属格子的所有任务。在执行前,业务线程可能优先结束而取消该任务的执行,例如在达到耗时阈值后,剖析任务已经或准备开始执行,但主线程取消了剖析任务这样一个临界点,此时可通过各语言的同步机制来及时取消剖析任务。lxR28资讯网——每日最新资讯28at.com

任务执行时,剖析线程将周期性采集线程的堆栈,而为了方便后续的分析工作,也会同时记录当前堆栈产生的时间戳,直到业务线程发出中断通知,或采集样本数达到上限,或任务状态发生改变,然后中断剖析线程的执行。lxR28资讯网——每日最新资讯28at.com

执行完成后,将采集到的线程栈集 push 到诊断数据队列,等待数据导出线程消费此队列,并发送到服务端。这里需要注意,线程栈数据文本量一般不会太小,比如我们一个专门用于测试的应用,500ms 触发的阈值下的 HTTP 接口,每次请求让线程随机 Sleep 5s 以内,当接口耗时超过 3s,单次剖析产生的栈文本大小在 200KB 以上,因此这里需要有个参数,来控制队列默认长度,避免过多的堆栈快照挤兑内存。lxR28资讯网——每日最新资讯28at.com

整个任务执行流程如下图所示:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

数据预聚合&导出

预聚合工作将由独立的工作线程消费诊断数据队列后来做,即将多个线程快照合并为一个,降低网络 IO 开销。具体就是对于快照集中每个快照的栈帧,按照它的开始时间取快照集中相同栈帧的最小值,结束时间取快照集中相同栈帧的最大值这个规则进行聚合,流程如下图所示:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

而数据发送层就比较简单了,采用高性能无锁队列 Mpsc, 使用 gRPC 协议发送到诊断服务端:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

当然,为了降低业务系统的压力,也可以将原始数据直接落盘,由外部独立的采集器逐行采集然后发送到消息队列。lxR28资讯网——每日最新资讯28at.com

服务端设计

图片图片lxR28资讯网——每日最新资讯28at.com

服务端的架构主要考虑三个点:lxR28资讯网——每日最新资讯28at.com

数据接收

同 Otel 对 Trace 数据的处理思路类似,诊断数据发送请求需要快速地被响应,来减少客户端因请求延迟导致发送队列数据被丢弃的可能。因此,诊断服务端采用吞吐性能较好的 go 语言编写,而请求涉及到跨语言调用,协议层上,综合高效快速可靠因素,选用较成熟的 gRPC 协议进行通信。lxR28资讯网——每日最新资讯28at.com

数据接收并成功解析后,需异步将数据放入队列,这里我们选用采用了多副本机制的 Kafka 消息中间件,来满足诊断服务各模块之间的解耦,同时也保证诊断数据不丢失 。lxR28资讯网——每日最新资讯28at.com

数据解析&加工

诊断剖析数据消费组会去消费队列中的数据,将数据进行进一步解析,并且持久化处理,其中包括:lxR28资讯网——每日最新资讯28at.com

  • a) 父子栈帧推导

客户端的预聚合会将多个快照合并为一个,因此快照内的每个栈帧将拥有不同的起始和结束时间。由于 Java 的原始线程堆栈是无层级的结构,为了提高数据的可读性,进一步降低高耗时问题定位发现的成本,因此需将已合并的堆栈进一步推导为包含父子栈帧的结构化信息,即从栈顶的第二个栈帧开始遍历调用栈,若当前栈帧的快照开始和结束的时间范围位于上个栈帧的左开右闭或左闭右开区间,则将当前栈帧设置为上个栈帧的子栈:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

注意:lxR28资讯网——每日最新资讯28at.com

1. 一个 Java 线程的大部分调用栈形式本身就是个从 "Thread.run" 开始的嵌套,而每次快照时也无从得知层级信息,因此不考虑推导快照开始和结束时间完全一致的栈帧,将这些栈帧置为同级即可。lxR28资讯网——每日最新资讯28at.com

2. 使用线程的快照时间来推导还原父子栈和耗时仍然是个相对比较粗略的统计行为,其精度受到当前线程调用栈快照导出的耗时,以及每次快照的间隔耗时的影响,因此父子层级结果仅供参考,并不绝对等于实际调用的关系结果。lxR28资讯网——每日最新资讯28at.com

  • b) 自身耗时计算

当已推导出父子栈帧关系后,可对结果集进行遍历,计算自身耗时,计算规则如下:lxR28资讯网——每日最新资讯28at.com

  • 从第二个栈帧开始,如果与上一个栈帧的快照开始和结束时间一致,则上个栈帧的自身耗时设为 0,否则会将当前栈帧的父栈帧(若存在)的自身耗时减掉上个栈帧的自身耗时。
  • 如果当前栈帧是最后一个,则将当前栈帧自身耗时设为快照开始与结束的时间差,并且将当前栈帧的父栈帧(若存在)的自身耗时减掉当前栈帧的自身耗时。
  • 如果当前栈帧有子栈帧,处理方式同上。

以上图调用时序为例,根据以上规则得出的自身耗时计算示意图如下:lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • c) 数据持久化

当完成父子栈帧推导和自身耗时计算后,数据将持久化存储,例如将数据存储到 ClickHouse,供数据查询端使用。lxR28资讯网——每日最新资讯28at.com

数据查询

诊断剖析数据将以 HTTP API 形式对外提供查询服务,例如可观测性门户系统,可根据线程名,链路 Trace ID, Span ID 等特征进行剖析数据的查询。lxR28资讯网——每日最新资讯28at.com

[    {        "data": "YXQgc3VuLm5pby5jaC5Vd...",//线程剖析栈        "thread_name": "XNIO-1 I/O-1",//线程名称        "thread_state": "RUNNABLE",//线程状态        "trigger_millisecond": 500,//触发阈值        "self_millisecond": 38,//自身耗时        "source_snapshot_count": 153//快照数    },    {        "data": "YXQgaW8udW5kZXJ0b3cuc2Vy...",        "thread_name": "XNIO-1 task-1",        "thread_state": "RUNNABLE",        "trigger_millisecond": 500,        "self_millisecond": 0,        "source_snapshot_count": 140    }]

调用链关联

线程剖析能结合 OpenTelemetry ,借助 OpenTelemetry Java Instrumentation 上下文的生命周期,从而关联 Trace ID 、接口名等链路特征。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

自身监控指标

线程剖析功能需要拥有较完善的自身监控,以便观测复杂剖析流程下对业务系统潜在的性能影响。这些监控包括:lxR28资讯网——每日最新资讯28at.com

  • 任务检测队列大小

检测队列用于给时间轮提供任务,该指标的大小给线程剖析的采样,接口名,线程名称等条件提供了一定参考。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 任务释放平均耗时

剖析任务的释放将会中断正在执行的剖析任务,其中涉及到剖析、数据状态机的改变,线程的中断。多线程情况下,需保证操作的原子性,如果任务释放的平均耗时变长,则能反映当前业务系统 CPU 线程上下文切换效率下降。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 正在执行剖析任务的个数

线程剖析是以线程为单位来执行的,通过观测正在进行线程剖析的任务数,可反映出剖析功能繁忙的程度,以及帮助我们决策是否需要对同时剖析的任务数进行限制。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 线程堆栈导出平均耗时

线程栈导出方法的平均耗时,如果该操作耗时显著升高,且调用栈未有明显变化,则代表性能恶化。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 数据队列大小

指待发送到服务端的数据队列大小。lxR28资讯网——每日最新资讯28at.com

  • 数据入队速率

指待发送到服务端的数据入队的速率。lxR28资讯网——每日最新资讯28at.com

  • 数据合并平均耗时

数据发送前进行预聚合,将多个线程快照合并为一个,这个过程的平均耗时,该值可供剖析条件提供一定参考。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 线程栈快照导出发送平均字节

线程快照发送的请求包平均大小。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

  • 数据导出速率

线程快照发送的速率。lxR28资讯网——每日最新资讯28at.com

图片图片lxR28资讯网——每日最新资讯28at.com

对以上指标进行监控,也方便对相关参数进行调优,从而更好地在诊断剖析功能的完整性与服务性能之间做相关取舍。lxR28资讯网——每日最新资讯28at.com

三、结语

线程剖析为解决性能问题提供了有力支持。通过采集和分析线程栈信息,它能够帮助开发人员定位应用程序中的高耗时问题,为性能优化提供关键信息。本文详细介绍了线程剖析的基本思想和实现思路,以及客户端和服务端的设计架构。其核心思想是通过创建特定阈值触发的检测任务,监测高耗时问题,并将采集到的数据异步发送到剖析服务端进行进一步计算和分析。lxR28资讯网——每日最新资讯28at.com

此外,线程剖析的自身监控指标,这些指标有助于更好地了解剖析功能的性能和繁忙程度,以便进行决策和调优。线程剖析不仅提供了性能数据,还可以与 OpenTelemetry 相结合,实现链路特征的关联,从而更全面地理解性能问题。lxR28资讯网——每日最新资讯28at.com

总的来说,线程剖析可以帮助开发人员提高应用程序的质量和性能,快速定位性能问题,以确保应用程序的顺畅运行,同时,也可以更有效地应对性能挑战,提高应用程序的可维护性和性能。lxR28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-26565-0.html线程剖析 - 助力定位代码层面高耗时问题

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: TypeScript 5.3 来了,一大波新特性

下一篇: 15个必知Pandas代码片段,助你精通数据分析

标签:
  • 热门焦点
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • CSS单标签实现转转logo

    转转品牌升级后更新了全新的Logo,今天我们用纯CSS来实现转转的新Logo,为了有一定的挑战性,这里我们只使用一个标签实现,将最大化的使用CSS能力完成Logo的绘制与动画效果。新logo
  • Automa-通过连接块来自动化你的浏览器

    1、前言通过浏览器插件可实现自动化脚本的录制与编写,具有代表性的工具就是:Selenium IDE、Katalon Recorder,对于简单的业务来说可快速实现自动化的上手工作。Selenium IDEKat
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • 重估百度丨大模型,能撑起百度的“今天”吗?

    自象限原创 作者|程心 罗辑2023年之前,对于自己的“今天”,百度也很迷茫。“新业务到 2022 年底还是 0,希望 2023 年出来一个 1。”这是2022年底,李彦宏
  • 首发天玑9200+ iQOO Neo8系列发布首销售价2299元起

    2023年5月23日晚,iQOO Neo8系列正式发布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro强悍登场,限时售价3099元起;价位段最强性能手机iQOO Neo8同期上市
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • 联想YOGA 16s 2022笔记本将要推出,屏幕支持触控功能

    联想此前宣布,将于11月2日19:30召开联想秋季轻薄新品发布会,推出联想 YOGA 16s 2022 笔记本等新品。官方称,YOGA 16s 2022 笔记本将搭载 16 英寸屏幕,并且是一
Top