当前热文:golang pprof 监控系列(1) —— go trace 统计原理与使用
服务监控系列文章
服务监控系列视频
【资料图】
关于go tool trace的使用,网上有相当多的资料,但拿我之前初学golang的经验来讲,很多资料都没有把go tool trace中的相关指标究竟是统计的哪些方法,统计了哪段区间讲解清楚。所以这篇文章不仅仅会介绍go tool trace的使用,也会对其统计的原理进行剖析。
golang版本 go1.17.12
先简单说下go tool trace 的使用场景,在分析延迟性问题的时候,go tool trace能起到很重要的作用,因为它会记录各种延迟事件并且对其进行时长分析,连关键代码位置也能找出来。
关于trace的实战案例,之前有出过一个视频(一次系统延迟分析案例),欢迎浏览
接着我们简单看下golang 里如何使用trace 功能。
go trace 使用package mainimport (_ "net/http/pprof""os""runtime/trace")func main() {f, _ := os.Create("trace.out")defer f.Close()trace.Start(f)defer trace.Stop() ......}
使用trace的功能其实比较容易,用trace.Start 便可以开启trace的事件采样功能,trace.Stop 则停止采用,采样的数据会记录到trace.Start 传来的输出流参数里,这里我是将一个名为trace.out 的文件作为输出流参数传入。
采样结束后便可以通过 go tool trace trace.out命令对采样文件进行分析了。
go tool trace 命令默认会使用本地随机一个端口来启动一个http服务,页面显示如下:
接着我会分析下各个链接对应的统计信息以及背后进行统计的原理,好的,接下来,正戏开始。
统计原理介绍平时在使用prometheus对应用服务进行监控时,我们主要还是采用埋点的方式,同样,go runtime内部也是采用这样的方式对代码运行过程中的各种事件进行埋点,最后读取 整理后的埋点数据,形成我们在网页上看的trace监控图。
// src/runtime/trace.go:517func traceEvent(ev byte, skip int, args ...uint64) {mp, pid, bufp := traceAcquireBuffer() .....}
每次要记录相应的事件时,都会调用traceEvent方法,ev代表的是事件枚举,skip 是看栈帧需要跳跃的层数,args 在某些事件需要传入特定参数时传入。
在traceEvent 内部同时也会获取到当前事件发生时的线程信息,协程信息,p运行队列信息,并把这些信息同事件一起记录到一个缓冲区里。
// src/runtime/trace/trace.go:120 func Start(w io.Writer) error {tracing.Lock()defer tracing.Unlock()if err := runtime.StartTrace(); err != nil {return err}go func() {for {data := runtime.ReadTrace()if data == nil {break}w.Write(data)}}()atomic.StoreInt32(&tracing.enabled, 1)return nil}
在我们启动trace.Start方法的时候,同时会启动一个协程不断读取缓冲区中的内容到strace.Start 的参数中。
在示例代码里,trace.Start 方法传入名为trace.out文件的输出流参数,所以在采样过程中,runtime会将采集到的事件字节流输出到trace.out文件,trace.out文件在被读取出的时候 是用了一个叫做Event的结构体来表示这些监控事件。
// Event describes one event in the trace.type Event struct {Off int // offset in input file (for debugging and error reporting)Type byte // one of Ev*seq int64 // sequence numberTs int64 // timestamp in nanosecondsP int // P on which the event happened (can be one of TimerP, NetpollP, SyscallP)G uint64 // G on which the event happenedStkID uint64 // unique stack IDStk []*Frame // stack trace (can be empty)Args [3]uint64 // event-type-specific argumentsSArgs []string // event-type-specific string args// linked event (can be nil), depends on event type:// for GCStart: the GCStop// for GCSTWStart: the GCSTWDone// for GCSweepStart: the GCSweepDone// for GoCreate: first GoStart of the created goroutine// for GoStart/GoStartLabel: the associated GoEnd, GoBlock or other blocking event// for GoSched/GoPreempt: the next GoStart// for GoBlock and other blocking events: the unblock event// for GoUnblock: the associated GoStart// for blocking GoSysCall: the associated GoSysExit// for GoSysExit: the next GoStart// for GCMarkAssistStart: the associated GCMarkAssistDone// for UserTaskCreate: the UserTaskEnd// for UserRegion: if the start region, the corresponding UserRegion end eventLink *Event}
来看下Event事件里包含哪些信息:P 是运行队列,go在运行协程时,是将协程调度到P上运行的,G 是协程id,还有栈id StkID ,栈帧 Stk,以及事件发生时可以携带的一些参数Args,SArgs。Type 是事件的枚举字段,Ts是事件发生的时间戳信息,Link 是与事件关联的其他事件,用于计算关联事件的耗时。
拿计算系统调用耗时来说,系统调用相关的事件有GoSysExit,GoSysCall 分别是系统调用退出事件和系统调用开始事件,所以GoSysExit.Ts - GoSysCall.Ts 就是系统调用的耗时。
特别提示: runtime 内部用到的监控事件枚举在src/runtime/trace.go:39 位置 ,而 在读取文件中的监控事件用到的枚举是 在src/internal/trace/parser.go:1028 ,虽然是两套,但是值是一样的。
很明显Link 字段不是在runtime 记录监控事件时设置的,而是在读取trace.out里的监控事件时,将事件信息按照协程id分组后 进行设置的。同一个协程的 GoSysExit.Ts - GoSysCall.Ts 就是该协程的系统调用耗时。
接下来我们来挨个分析下trace页面的统计信息以及背后的统计原理。
View trace是每个事件的时间线构成的监控图,在生产环境下1s都会产生大量的事件,我认为直接看这张图还是会让人眼花缭乱。 所以还是跳过它吧,从Goroutine analysis开始分析。
Goroutine analysisgo tool trace最终引用的代码位置是在go/src/cmd/trace 包下,main函数会启动一个http服务,并且注册一些处理函数,我们点击Goroutine analysis 其实就是请求到了其中一个处理函数上。下面这段代码是注册的goroutine的处理函数点击Goroutine analysis 就会映射到 /goroutines 路由上。
// src/cmd/trace/goroutines.go:22func init() {http.HandleFunc("/goroutines", httpGoroutines)http.HandleFunc("/goroutine", httpGoroutine)}
让我们点击下 Goroutine analysis
进入到了一个显示代码调用位置的列表,列表中的每个代码位置都是事件EvGoStart 协程开始运行时的位置,其中N代表 在采用期间 在这个位置上有N个协程开始过运行。
你可能会好奇,是怎样确定这10个协程是由同一段代码执行的?runtime在记录协程开始执行的事件EvGoStart 时,是会把栈帧也记录下来的,而栈帧中包含函数名和程序计数器(PC)的值,在Goroutine analysis 页面 中就是协程就是按PC的值进行分组的。 以下是PC赋值的代码片段。
// src/internal/trace/goroutines.go:176case EvGoStart, EvGoStartLabel:g := gs[ev.G]if g.PC == 0 {g.PC = ev.Stk[0].PCg.Name = ev.Stk[0].Fn}
我们再点击第一行链接 nfw/nfw_base/fw/routine.(*Worker).TryRun.func1 N=10 ,这里点击第一行的链接将会映射到 /goroutine 的路由上(注意路由已经不是s结尾了),由它的处理函数进行处理。点击后如图所示:
现在看到的就是针对这10个协程分别的系统调用,阻塞,调度延迟,gc这些统计信息。
接着我们从上到下挨个分析:Execution Time 是指着10个协程的执行时间占所有协程执行的比例。接着是用于分析网络等待时间,锁block时间,系统调用阻塞时间 ,调度等待时间的图片,这些都是分析系统延迟,阻塞问题的利器。 这里就不再分析图了,相信网上会有很多这种资料。
然后来看下 表格里的各项指标:
Execution是协程在采样这段时间内的执行时间。
记录的方式也很简单,在读取event事件时,是按时间线从前往后读取,每次读取到协程开始执行的时间时,会记录下协程的开始执行的时间戳(时间戳是包含在Event结构里的),读取到协程停顿事件时,则会把停顿时刻的时间戳减去开始执行的时间戳 得到 一小段的执行时间,将这小段的时间 累加到该协程的总执行时间上。
停顿则是由锁block,系统调用阻塞,网络等待,抢占调度造成的。
Network wait顾名思义,网络等待时长, 其实也是和Execution类似的记录方式,首先记录下协程在网络等待时刻的时间戳,由于event是按时间线读取的,当读取到unblock事件时,再去看协程上一次是不是网络等待事件,如果是的话,则将当前时刻时间戳减去 网络等待时刻的时间戳,得到的这一小段时间,累加到该协程的总网络等待时长上。
Sync block,Blocking syscall,Scheduler wait这三个时长 计算方式和前面两张也是类似的,不过注意下与之相关联的事件的触发条件是不同的。
Sync block 时长是由于 锁 sync.mutex ,通道channel,wait group,select case语句产生的阻塞都会记录到这里。 下面是相关代码片段。
// src/internal/trace/goroutines.go:192case EvGoBlockSend, EvGoBlockRecv, EvGoBlockSelect,EvGoBlockSync, EvGoBlockCond:g := gs[ev.G]g.ExecTime += ev.Ts - g.lastStartTimeg.lastStartTime = 0g.blockSyncTime = ev.Ts
Blocking syscall 就是系统调用造成的阻塞了。
Scheduler wait 是协程从可执行状态到执行状态的时间段,注意协程是可执行状态时 是会放到p 运行队列等待被调度的,只有被调度后,才会真正开始执行代码。 这里涉及到golang gpm模型的理解,这里就不再展开了。
后面两栏就是GC 占用total时间的一个百分比了,golang 的gc相关的知识也不继续展开了。
各种profile 图还记得最开始分析trace.out生成的网页时,Goroutine analysis 下面是什么吗?是各种分析延迟相关的profile 图,数据的来源和我们讲Goroutine analysis 时分析单个Goroutine 的等待时间的指标是一样的,不过这里是针对所有goroutine而言。
Network blocking profile (⬇)Synchronization blocking profile (⬇)Syscall blocking profile (⬇)Scheduler latency profile (⬇)
关于golang 的这个trace工具,还允许用户可以自定义监控事件 ,生成的trace网页里,User-defined tasks,User-defined regions 就是记录用户自定义的一些监控事件,这部分的应用等到以后再讲了。
Minimum mutator utilization 是一个看gc 对程序影响情况的曲线图,这个等以后有机会讲gc时再详细谈谈了。
关于trace的实战案例,之前有出过一个视频(一次系统延迟分析案例),欢迎浏览。
标签:
推荐文章
- 研究人员最新发现 单个细胞可同时处理成百上千个信号
- 长期暴露在光照下性能退化 科学家发现钙钛矿太阳能电池最大缺陷
- 陆军第73集团军某旅 创新升级模拟训练器材
- 陆军炮兵防空兵学院 毕业学员综合战术演习现地备课工作圆满完成
- 宁夏启动双百科技支撑行动 构建高水平产业创新体系
- 区域特色产业转型升级 四川屏山以“3+”模式推进科技创新工作
- 国内首颗以茶叶冠名遥感卫星 安溪铁观音一号发射成功
- 激发创新动能促进产业发展 无锡滨湖走出产业转型“绿色”路
- 走近网瘾少年们:他们沉迷网络的病根何在?
- 节后第一天北京白天晴或多云利于出行 夜间起秋雨或再上线
- 走访抗美援朝纪念馆:长津湖的寒冷,与战斗一样残酷
- 绥化全域低风险!黑龙江绥化北林区一地调整为低风险
- 农业农村部:确保秋粮丰收到手、明年夏季粮油播种
- 中国故事丨“沉浸式”盘点今年的教育好声音!
- 升旗、巡岛、护航标、写日志,他们一生守护一座岛
- 他从一窍不通的“门外汉”,到重装空投“兵专家”
- 获2021年诺奖的蛋白,结构由中国学者率先解析
- “双减”后首个长假:亲子游、研学游需求集中释放
- 天山脚下,触摸丝路发展新脉动
- 且看新疆展新颜
- 《山海情》里“凌教授”的巨菌草丰收啦
- “双减”出台两个月,组合拳如何直击减负难点?
- IP类城市缘何吸引力强?玩法创新带动游客年轻化
- 面对婚姻,“互联网世代”的年轻人在忧虑什么?
- 沙害是自然界的恶魔,而他是荒沙碱滩的征服者
- “辱华车贴”商家及客服被行拘,处罚要不放过每一环
- 网游新政下,未成年人防沉迷的“主战场”在哪?
- 160万骑手疑似“被个体户”?平台不能当甩手掌柜
- 报告显示:这个国庆假期,粤川浙桂赣旅游热度最高
- 陈毅元帅长子忆父亲叮嘱:你们自己学习要好,就可以做很多事儿
- 北京国庆7天接待游客超861万人次 冬奥线路受青睐
- 从1.3万元降到700元,起诉书揭秘心脏支架“玄机”
- 都市小资还是潮流乐享?花草茶市场呈爆发性增长
- 国庆主题花坛持续展摆至重阳节
- 警方查处故宫周边各类违法人员12人
- 云南保山:170公里边境线,4000余人日夜值守
- 线上教学模式被盯上,网络付费刷课形成灰色产业链
- 全国模范法官周淑琴:为乡村群众点燃法治明灯
- 嘉陵江出现有记录以来最强秋汛
- 中国科技人才大数据:广东总量第一,“北上”这类人才多
- 神经科学“罗塞塔石碑”来了:迄今为止最完整的大脑细胞图谱
- 多地网友投诉遭遇旅游消费骗局,呼吁有关部门严查乱象
- 受南海热带低压影响 海南海口三港预计停运将持续到10日白天
- 农业农村部:确保秋粮丰收到手、明年夏季粮油播种
- 广州10月8日至20日对所有从省外来(返)穗人员实施核酸检测
- 辽宁省工信厅发布10月8日电力缺口橙色预警
- 受琼州海峡封航影响 10月7日、8日进出海南岛旅客列车停运
- 这场红色故事“云比拼”,穿越时空为我们指引方向
- 陕西支援14省份采暖季保供用煤3900万吨
- 汾河新绛段发生决口
- 看,生机勃勃的中国
- 百闻不如一见——北京大学留学生参访新疆
- 新疆霍尔果斯市2例无症状感染者新冠病毒均为德尔塔变异株
- 哈尔滨市南岗区爱达88小区将调整为低风险地区
- 国庆假期全国道路交通总体安全平稳有序
- 假期怎么过得这么快?国庆5.15亿人次出游,你咋过的?
- 国庆假期北京接待游客861.1万人次
- 山西平遥消防4天29次救援:拖着腿走路也要完成任务
- 新疆兵团可克达拉市:195名密接者已全部隔离医学观察
- 国庆假期中国预计发送旅客4.03亿人次
- 公安部交管局:国庆假期日均出动警力18万余人次,5位交警辅警牺牲
- 国庆假期中国国内旅游出游5.15亿人次
- 新疆哈密市巴里坤县发生4.3级地震 震源深度9千米
- 冷空气自西向东影响中国大部地区 气温将下降4℃至6℃
- 2021年MAGIC3上海市青少年三对三超级篮球赛落幕
- 国庆假期广西累计接待游客逾3611万人次 实现旅游消费272.41亿元
- 新疆伊犁州:妥善做好滞留旅客安置返回工作
- 新疆霍尔果斯无症状感染者新冠病毒属德尔塔变异株 未发现高度同源的基因组序列
- “数说”杭州无障碍改造:触摸城市“爱的厚度”
- 受南海热带低压影响广东将暂别高温天气
- 浙南沿海村村发展有妙招 搭乘共富快车打造“海上花园”
- 世界第一埋深高速公路隧道大峡谷隧道出口端斜井掘进完成
- 直径2米“面气球”亮相 山西首届“寿阳味道”美食大赛启幕
- 厦门同安区四区域调整为低风险 全市无中高风险地区
- 哥伦比亚遇上广州:洋茶人“云上”喫茶 传播中国茶“味道”
- 新疆兵团第四师可克达拉市1名无症状感染者为餐饮从业人员
- 中国国庆假期出行热:数字改变“关键小事”
- 添加陌生人为好友 内蒙古两女子被骗126万
- 南沙港铁路国庆假期不停工 力争今年年底开通
- 新疆霍尔果斯两例无症状感染者新冠病毒均属德尔塔变异株
- 哈尔滨一地风险等级调整为低风险
- 哈尔滨市学校有序恢复线下教学
- 受热带低压影响 琼州海峡北岸等待过海车辆排长龙
- 铁路迎返程高峰 西安局集团公司加开79趟高铁列车
- 铁路人国庆雨中巡查排险记:一身雨衣、一把铁锹保安全畅通
- 水能载物亦能“生金” 浙江遂昌山村以水为媒奔共富
- 科学拦峰错峰削峰 嘉陵江洪水过境重庆中心城区“有惊无险”
- 山西解除持续近90小时的暴雨四级应急响应
- 安徽黄山国庆假期迎客12万余人 旅游市场稳步复苏
- 从进“培训班”到看《长津湖》
- 厦门中高风险地区清零 撤除离厦通道查验点
- 济南趵突泉地下水位创1966年以来最高纪录
- 杭州“十一”假期后初中取消统一早读
- “颜值担当”里的中国,映照“万物和谐”新气象
资讯
行业动态
-
当前热文:golang pprof 监控系列(1) —— go trace 统计原理与使用
- 当前热文:golang pprof 监控系列(1) —— go trace 统计原理与使用
- 域高国际控股(01621.HK):许颖雯辞任执行董事
- 报道:一女子退休丈夫送车送花 连退休都搞得这么浪漫!酸死了!
- 环球热文:dcs world配置要求高吗_dcs world
- 牛皮癣能吃麻子菜吗
- 最新消息:为什么ungo因果日记没有火起来
- 全球热消息:瘦身馆简介_瘦身馆
- 《了不起的夜晚》3月25日、26日在全国五十三城开启点映, 新鲜喜剧类型获赞_速看料
- 浙江众成3月24日快速上涨
- TikTok面临被禁危机,CEO周受资回应信息安全等问题 当前最新