对golang的io型进程进行off-cpu分析
背景:
对于不能占满所有cpu核数的进程,进行on-cpu的分析是没有意义的,因为可能程序大部分时间都处在阻塞状态。

实验例子程序:
以centos8和golang1.23.3为例,测试下面的程序:
pprof_netio.go
package mainimport ("fmt""net/http"_ "net/http/pprof"//"time"
)func main() {go func() {_ = http.ListenAndServe("0.0.0.0:9091", nil)}()//并发数var ConChan = make(chan bool, 100)for {ConChan <- truego func() {defer func() {<-ConChan}()doNetIO()}()}
}func doNetIO() {//fmt.Printf("doNetIO start: %s\n", time.Now().Format(time.DateTime))for i := 0; i < 10; i++ {_, err := http.Get("http://127.0.0.1:8080/echo_delay")if err != nil {fmt.Printf("i:%d err: %v\n", i, err)return}}//fmt.Printf("doNetIO end: %s\n", time.Now().Format(time.DateTime))
}
测试请求的是nginx,nginx配置如下:
agent-8080.conf
server{listen 8080 reuseport;index index.html index.htm index.php;root /usr/share/nginx/html;access_log /var/log/nginx/access-8080.log main;error_log /var/log/nginx/access-8080.log error;location ~ /echo_delay {limit_rate 30;return 200 '{"code":"0","message":"ok","data":"012345678901234567890123456789"}';}location ~ /*.mp3 {root /usr/share/nginx/html;limit_rate 10k;}location ~ /* {return 200 '{}';}
}
编译运行程序:
go build pprof_netio.go
./pprof_netio
top查看,cpu利用率非常低:

通过pprof:profile查看on-cpu耗时情况:
go tool pprof -http=192.168.36.5:9000 http://127.0.0.1:9091/debug/pprof/profile

默认采样总时长30s,on-cpu时间才690ms,准确说是在30s内只采样到69次,每次采样间隔10ms,pprof推算on-cpu时间是690ms,总之cpu利用率很低。
通过perf查看off-cpu耗时情况:
查看perf支持的调度事件:

以centos8为例,安装依赖:
yum install kernel-debug kernel-debug-devel --nogpgcheck
echo 1 > /proc/sys/kernel/sched_schedstats
perf生成off-cpu火焰图脚本:
perf-offcpu.sh
#/bin/shif [ "$1" == "" ]; thenecho “usage: $0 prog_name”exit
fi
pid=`ps aux | grep $1 | grep -v 'grep' | grep -v 'perf-offcpu' | awk '{print $2}'`
echo prog_name:$1
echo pid:$pid
perf record -e sched:sched_stat_sleep -e sched:sched_switch \-e sched:sched_stat_iowait -e sched:sched_process_exit \-e sched:sched_stat_blocked -e sched:sched_stat_wait \-g -o perf.data.raw -p $pid -- sleep 30
perf inject -v -s -i perf.data.raw -o perf.data
perf script -F comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace | awk 'NF > 4 { exec = $1; period_ms = int($5 / 1000000) }NF > 1 && NF <= 4 && period_ms > 0 { print $2 }NF < 2 && period_ms > 0 { printf "%s\n%d\n\n", exec, period_ms }' | \stackcollapse.pl | \flamegraph.pl --countname=ms --title="Off-CPU Time Flame Graph" --colors=io > offcpu.svg
进行采样:
sh perf-offcpu.sh 'pprof_netio'
perf的off-cpu火焰图:

可以看出阻塞时间的65%都在等待网络连接的建立、发送、读取。
通过bcc/tools/offcputime查看off-cpu耗时情况:
centos8安装bcc-tools:
yum install bcc-tools --nogpgcheck
bcc生成off-cpu火焰图脚本:
bcc-offcputime.sh
#/bin/shif [ "$1" == "" ]; thenecho “usage: $0 prog_name”exit
fi
pid=`ps aux | grep $1 | grep -v 'grep' | grep -v 'bcc-offcputime' | awk '{print $2}'`
echo prog_name:$1
echo pid:$pid
/usr/share/bcc/tools/offcputime -df -p $pid 30 > out.stacks
flamegraph.pl --color=io --title="bcc Off-CPU Time Flame Graph" --countname=us < out.stacks > offcpu-bcc.svg
进行采样:
sh bcc-offcputime.sh 'pprof_netio'
bcc的off-cpu火焰图:

可以看出阻塞时间的67%都在等待网络连接的建立、发送、读取。
通过fgprof以代码侵入方式对golang程序进行off-cpu耗时分析:
修改代码,添加fgprof支持:
pprof_netio.go
package mainimport ("fmt""net/http"_ "net/http/pprof"//"time""github.com/felixge/fgprof"
)func main() {//fgprof支持http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())go func() {_ = http.ListenAndServe("0.0.0.0:9091", nil)}()//并发数var ConChan = make(chan bool, 100)for {ConChan <- truego func() {defer func() {<-ConChan}()doNetIO()}()}
}func doNetIO() {//fmt.Printf("doNetIO start: %s\n", time.Now().Format(time.DateTime))for i := 0; i < 10; i++ {_, err := http.Get("http://127.0.0.1:8080/echo_delay")if err != nil {fmt.Printf("i:%d err: %v\n", i, err)return}}//fmt.Printf("doNetIO end: %s\n", time.Now().Format(time.DateTime))
}
进行fgprof采样:
go tool pprof --http=192.168.36.5:9000 http://localhost:9091/debug/fgprof?seconds=30
fgprof的off-cpu火焰图:

从图看,能大致定位到是阻塞在网络读写上,但给人感觉采样的范围和频率不及perf和bcc,而且看资料不支持采样cgo程序。
参考资料:
Off-CPU Flame Graphs
Linux perf_events Off-CPU Time Flame Graph
fgprof package - github.com/felixge/fgprof - Go Packages
--end--
相关文章:
对golang的io型进程进行off-cpu分析
背景: 对于不能占满所有cpu核数的进程,进行on-cpu的分析是没有意义的,因为可能程序大部分时间都处在阻塞状态。 实验例子程序: 以centos8和golang1.23.3为例,测试下面的程序: pprof_netio.go package m…...
Springboot中使用Retrofit
Retrofit官网 https://square.github.io/retrofit/ 配置gradle implementation("com.squareup.okhttp3:okhttp:4.12.0")implementation ("com.squareup.retrofit2:retrofit:2.11.0")implementation ("com.squareup.retrofit2:converter-gson:2.11.0…...
Ubuntu中配置内网固定IP
文章目录 背景一、配置步骤(一)首先确认网卡名称(二)确认网关(三)备份配置文件(四)编辑配置文件(五)应用配置(六)验证配置 二、注意事…...
ExcelVBA编程输出ColorIndex与对应颜色色谱
标题 ExcelVBA编程输出ColorIndex与对应颜色色谱 正文 解决问题编程输出ColorIndex与对应色谱共56,打算分4纵列输出,标题是ColorIndex,Color,Name 1. 解释VBA中的ColorIndex属性 在VBA(Visual Basic for Applications)中ÿ…...
MySQL中in和exists的使用场景
在MySQL中,IN 和 EXISTS 是用于子查询的两种常见方法,它们在不同的场景下有不同的表现和适用性。下面我将详细介绍这两种方法的使用场景、优劣,并通过实验来说明问题。 IN 子查询 使用场景: 当子查询返回的结果集较小且不包含 …...
【多线程2】start 和 run 区别,终止线程,等待线程
Thread 类使用 start 方法,启动一个线程,对于同一个 Thread 对象来说,start 只能调用一次!!! 不怕名字起的长,就怕含义不清楚! 想要启动更多线程,就是得创建新的对象&am…...
富途证券C++面试题及参考答案
C++ 中堆和栈的区别 在 C++ 中,堆和栈是两种不同的内存区域,它们有许多区别。 从内存分配方式来看,栈是由编译器自动分配和释放的内存区域。当一个函数被调用时,函数内的局部变量、函数参数等会被压入栈中,这些变量的内存空间在函数执行结束后会自动被释放。例如,在下面的…...
Go使用sqlx操作MySQL完整指南
# Go使用sqlx操作MySQL完整指南## 1. 安装依赖bash go get github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx2. 数据库基础操作 package mainimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx" )// 定…...
Python 爬取网页文字并保存为 txt 文件教程
引言 在网络数据获取的过程中,我们常常需要从网页中提取有用的文字信息。Python 提供了强大的库来帮助我们实现这一目标。本教程将以https://theory.gmw.cn/2023 - 08/31/content_36801268.htm为例,介绍如何使用requests库和BeautifulSoup库爬取网页文字…...
时间序列预测论文阅读和相关代码库
时间序列预测论文阅读和相关代码库列表 MLP-based的时间序列预测资料DLinearUnetTSFPDMLPLightTS 代码库以及论文库:Time-Series-LibraryUnetTSFLightTS MLP-based的时间序列预测资料 我会定期把我的所有时间序列预测论文有关的资料链接全部同步到这个文章中&#…...
Mamba安装环境和使用,anaconda环境打包
什么是mamba Mamba是一个极速版本的conda,它是conda的C重新实现,使用多线程并行处理来加速包和依赖项的下载。 Mamba旨在提高安装、更新和卸载Python包的速度,同时保持与conda相同的兼容性和命令行接口。 Mamba的核心部分使用C实现ÿ…...
SSH连接成功,但VSCode连接不成功
环境 在实验室PC上连接服务器234 解决方案:在VSCode中重新添加远程主机 删除旧的VSCode Server 在远程主机上,VSCode会安装一个‘vscode-server’服务来支持远程开发,有时旧的‘vscode-server’文件可能会导致问题,删除旧的&am…...
springboot结合AES和国密SM4进行接口加密
api接口加密 1.为什么需要api接口加密呢? 1.防止爬虫 2.防止数据被串改 3.确保数据安全 2.如何实现接口加密呢? 3.我们可以使用哪些加密算法来加密呢? AES 密码学中的高级加密标准(Advanced Encryption Standard,…...
iOS在项目中设置 Dev、Staging 和 Prod 三个不同的环境
在 Objective-C 项目中设置 Dev、Staging 和 Prod 三个不同的环境,并为每个环境使用不同的 Bundle ID,可以通过以下步骤实现: 步骤 1: 创建不同的 Build Configuration 打开项目: 启动 Xcode 并打开你的项目。 选择项目文件&…...
openeuler24.09 系统无需配置 docker 源即可安装 docker 和 docker-composer
准备工作 1、准备一台刚刚创建的 openeuler24.09 lxc 虚拟机 2、使用 dnf 更新到最新,安装常用 工具 dnf update -y dnf install vim net-tools wget3、设置 ssh 由于ssh 与通常网上教程大同小异,在此我们就略过。 从下图我们可以看到 openeuler24.09 已经远程连接上。 …...
Flask入门:打造简易投票系统
目录 准备工作 创建项目结构 编写HTML模板 编写Flask应用 代码解读 进一步优化 结语 Flask,这个轻量级的Python Web框架,因其简洁和易用性,成为很多开发者入门Web开发的首选。今天,我们就用Flask来做一个简单的投票系统,让你快速上手Web开发,同时理解Flask的核心概…...
日常思考笔记
技术管理, 团队管理,人才培养,梯队建设 项目管理,项目全生命周期,项目进度 考核规范, AQS 是CountDownLatch,ReentrantLock,Semaphore,ReentrantReadWriteLock的基础 vo…...
【JAVA】后台管理系统密码复杂度和修改密码处理
一、后台管理系统密码要求 后台管理系统密码要求 口令有效期:90天 口令长度8位及8位以上 口令复杂度要求,至少包含以下四类字符中的三类字符: 英文大写字母(A 到 Z)、英文小写字母(a 到 z)、10个基本数字(0 到 9)、特殊字符(例如 !、$、#、%、、^、&a…...
微服务SpringCloud链路追踪之Micrometer+Zipkin
视频教程: https://www.bilibili.com/video/BV12LBFYjEvR 效果演示 当我们发送一个请求给 Gateway 的时候,由 Micrometer trace 进行链路追踪和数据收集,由 Zipkin 进行数据展示。可以清楚的看到微服务的调用过程,以及每个微服务…...
Quartz(2-Trigger)
相关文章链接 定时任务工具类(Cron Util)SpringBoot TaskQuartz(1-Job)Quartz(2-Trigger) Trigger 方法 优先级(priority) 如果你的 trigger 很多(或者 Quartz 线程…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...
【threejs】每天一个小案例讲解:创建基本的3D场景
代码仓 GitHub - TiffanyHoo/three_practices: Learning three.js together! 可自行clone,无需安装依赖,直接liver-server运行/直接打开chapter01中的html文件 运行效果图 知识要点 核心三要素 场景(Scene) 使用 THREE.Scene(…...
