Go怎么做性能优化工具篇之 trace工具

news/2024/12/23 16:16:34/

一、什么是 trace

trace 是 Go 语言的一个非常强大的性能分析工具,它用于追踪和记录 Go 程序的执行过程。与 CPU 和内存性能分析工具(如 pprof)不同,trace 侧重于在时间维度上分析程序的行为,帮助开发者理解程序执行中的时间分布、并发和调度等方面的细节。

二、如何使用 Go Trace

1、启用 trace

Go Trace 的启用非常简单。你只需要在程序中插入 runtime/trace 包,并在合适的地方启动和停止 trace。具体步骤如下:

package mainimport ("fmt""runtime/trace""os""time"
)func main() {// 创建一个文件来保存 trace 信息f, err := os.Create("trace.out")if err != nil {fmt.Println("could not create trace file:", err)return}// 启动 tracedefer f.Close()if err := trace.Start(f); err != nil {fmt.Println("could not start trace:", err)return}// 确保在函数退出时停止 tracedefer trace.Stop()// 模拟程序执行的任务simulateTask()
}func simulateTask() {// 模拟一段时间的工作fmt.Println("Task started")time.Sleep(2 * time.Second)fmt.Println("Task completed")
}

执行上述脚本后,会生成一个 trace.out 文件

2、分析trace文件

生成 trace 文件后,使用 go tool trace 命令来分析该文件。该命令会启动一个 web 界面,帮助你查看程序的详细执行过程。

go tool trace trace.out

执行该命令后,会启动一个本地的 Web 服务器
在这里插入图片描述
跳转打开之后
在这里插入图片描述
点击协程分析:
在这里插入图片描述
可以看到协程运行时间、同步阻塞时间、系统调用阻塞时间、调度延迟时间等。
如果发现某个数据不正常,可以点击看上面的链接,就可以定位到具体的阻塞代码了

当我们想要查看处理器的使用状况时,便可以使用处理器分析视图(View trace by Proc)。后面就是这个视图的样子。
在这里插入图片描述
借助处理器视图,我们可以了解到多核是否处于被充分使用,也能够知晓在某一特定时刻,处于不同状态的协程数量分别是多少。如果处于可调度(Runnable)状态的协程数量较多,可能意味着创建的协程数量过多,导致无法得到 CPU 的有效调度。而且我们还能够查看在那些占用处理器时间的各类事件当中,究竟哪些是由垃圾回收(GC)所占用的。倘若垃圾回收占用 CPU 的时间过多,这同样也意味着程序处于一种不健康的运行状态

以下是各个链接的说明:

2.1 View trace(常用)

是指查看完整的 trace 文件,观察程序的执行路径和执行过程,通常会包括以下信息:Goroutine 的生命周期、各种事件(如内存分配、垃圾回收)、调度、等待、阻塞等状态、Trace 数据通常通过 runtime/trace 包生成并保存为 .out 文件,之后通过 go tool trace 命令进行查看。

2.2 Goroutine analysis(常用)

这一部分显示了所有 Goroutine 的活动和状态。Go 的并发模型是基于 Goroutines(轻量级线程)实现的,而通过 Goroutine 分析,你可以:看到每个 Goroutine 执行的任务、分析 Goroutine 是否在阻塞、等待或过度创建等情况、观察 Goroutine 的调度、启动和终止等

2.3 Network blocking profile

这一部分分析网络相关的阻塞情况,通常是程序在进行网络操作时(例如 HTTP 请求、数据库连接等)发生的阻塞。它显示了因为网络操作而导致的延迟或卡住的情况。具体来说,可能的网络阻塞包括:

  • 网络请求的等待时间(如 DNS 查询、HTTP 请求等待等)
  • 网络连接建立和关闭的阻塞
  • 数据传输时的等待
    这种阻塞通常会影响应用程序的响应性和性能,因此网络阻塞分析对于优化程序的网络操作至关重要。
2.4 Synchronization blocking profile

Synchronization blocking profile 分析了程序中由于同步操作(如锁、信号量、条件变量等)而发生的阻塞情况。这类同步操作通常是为了保护共享资源,防止数据竞态问题。阻塞通常发生在以下场景:
竞争条件:多个 Goroutine 同时请求获取同一资源(例如,通过互斥锁 mutex)。
等待某些条件的发生(例如条件变量 Cond 的等待)。如果程序过度使用同步原语(例如 sync.Mutex 或 sync.WaitGroup),或者同步操作设计不当,可能会导致性能瓶颈。通过这部分分析,你可以了解在哪些同步点程序被阻塞,并优化同步的粒度和设计。

2.5 Syscall blocking profile

Syscall blocking profile 分析了程序在进行系统调用(如文件操作、网络 I/O、内存管理等)时发生的阻塞情况。Go 程序的系统调用通常是同步的,这意味着程序在等待 I/O 操作完成时会被阻塞。常见的系统调用包括:

  • 网络 I/O 操作(如 net.Dial、http.Get 等)
  • 文件 I/O 操作(如读写文件)
    操作系统的其他资源访问(如进程创建、内存分配等)
    如果应用程序的性能瓶颈出现在系统调用上,可能需要考虑优化 I/O 操作,减少阻塞的时间,或使用异步 I/O 模型。
2.6 Scheduler latency profile

Scheduler latency profile 分析了 Go 程序中调度器的延迟问题。Go 语言的调度器负责将 Goroutine 映射到操作系统线程,调度延迟可能会影响程序的响应时间和吞吐量。常见的调度延迟问题包括:

  • Goroutine 长时间没有被调度执行
  • 某些 Goroutine 被延迟调度,导致响应时间增加
  • 调度器的上下文切换过于频繁,影响程序性能

通过这一部分的分析,开发者可以确定是否存在调度瓶颈,并相应地优化 Goroutine 的调度策略,例如调整 Goroutine 的优先级、减少不必要的上下文切换等。

2.7 User-defined tasks

User-defined tasks 是程序员通过 runtime/trace 的 WithRegion 和 Eventf 等接口定义的自定义任务。Go 的 Trace 工具允许开发者手动标记特定的任务或操作,以便后续分析。例如,你可能会将某个重要的业务逻辑部分(如数据库查询、复杂计算等)标记为任务,并查看它的执行情况和性能。
用户定义任务 对于标记和分析关键代码路径非常有用,帮助开发者聚焦于特定部分的性能瓶颈。

2.8 User-defined regions

User-defined regions 是程序员自定义的代码区域,通常用 WithRegion 函数来标记。类似于自定义任务,区域是对程序执行的特定代码块进行的标记,用于分析该区域的执行时长和性能。例如,你可以在一个数据库查询操作的开始和结束处插入 WithRegion,以查看该查询所占用的时间。

用户定义区域 让开发者能够细粒度地分析程序的执行,并且将重点放在程序中耗时较长的区域上。

2.9 Minimum mutator utilization

Minimum mutator utilization 是 Go 程序中与垃圾回收(GC)相关的一个度量,表示在 GC 运行期间,程序的“变异器”(Mutator)部分的工作效率。变异器是指执行用户代码的部分,它在 GC 期间可能会被暂停或延迟。如果变异器的利用率较低,意味着 GC 占用了太多的 CPU 时间,导致应用程序性能下降。

Mutator:指执行用户代码的 Goroutine,它在垃圾回收的过程中会被暂停。
利用率:表示在 GC 期间,变异器代码的执行时间相对于 GC 停顿时间的比例。
最低变异器利用率 是评估垃圾回收效率和程序性能的一个指标。如果该值过低,说明 GC 的停顿时间过长,可能需要优化内存管理或减少垃圾回收的频率。

三、Go的性能优化代码实践(下篇)


http://www.ppmy.cn/news/1557509.html

相关文章

RHEL 7.5 源码安装 mysql-5.7.17 数据库

RHEL 7.5 mysql-5.7.17 源码安装 1、解决依赖包并下载源码包 # yum -y install gcc gcc-c ncurses ncurses-devel bison # wget https://sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz # tar -zxvf boost_1_59_0.tar.gz # mv boost_1_59_0 /usr/loc…

QtitanChart组件——高效、灵活的Qt数据可视化解决方案

在现代应用开发中,数据可视化已经成为不可或缺的一部分。无论是商业分析工具、财务报表、工程图表,还是科学实验数据展示,如何以直观、易理解的方式展示数据,往往决定了软件的可用性与用户体验。对于Qt开发者来说,Qtit…

SWIFT基本使用

安装 # 全量能力 pip install ms-swift[all] -U # 仅使用LLM pip install ms-swift[llm] -U # 仅使用AIGC pip install ms-swift[aigc] -U # 仅使用Adapters pip install ms-swift -U or git clone https://github.com/modelscope/ms-swift.git cd ms-swift pip install -e …

单片机与MQTT协议

MQTT 协议简述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布 / 订阅(publish/subscribe)模式的 “轻量级” 通讯协议,该协议构建于 TCP/IP 协议上&#xf…

【证书】免费的证书+1 Ai Prompt Engineer

碎片化的时间利用起来,获得个免费🆓的证书📖吧。 简单了解下相关知识,然后考试,几分钟🕰️就可以获得🉐个🆓的证书。超级超级简单的💕💕。 没什么含金量的哈…

前端数据可视化库介绍Echarts、D3.js、Plotly、Matplotlib

目录 一、Echarts 1. 简介 2. 优点 3. 缺点 4. 代码示例 二、D3.js 1. 简介 2. 优点 3.缺点 4. 代码示例 三、Plotly 1.简介 2.优点 3.缺点 四、Matplotlib 1.简介 2.优点 3.缺点 一、Echarts 1. 简介 Echarts 是一个由百度开源的数据可视化库,…

jenkins针对大文件进行拉取

pipeline { agent { kubernetes { inheritFrom maven containerTemplate{ name maven image jenkins_pipiline_base:latest } } } stages { stage(构建发布) { steps { container(maven) { script { …

智慧社区系统源码社区服务软件家政跑腿月嫂保洁维修小程序

应用场景 社区服务软件在现代社区生活中扮演着至关重要的角色,其应用场景涵盖了居民生活的方方面面,主要包括以下几个方面: 家政与生活服务: 家电维修与家庭保洁:居民可以通过软件预约专业的家电维修和家庭保洁服务&a…