今天,通过一个例子,一方面熟悉trace在自定义范围内的分析,另一方面golang 在协程调度策略上的浅析。

Show Code

// trace_example.go
package main import (
"context"
"fmt"
"os"
"runtime"
"runtime/trace"
"sync"
) func main(){
// 为了看协程抢占,这里设置了一个cpu 跑
runtime.GOMAXPROCS(1) f, _ := os.Create("trace.dat")
defer f.Close() _ = trace.Start(f)
defer trace.Stop() ctx, task := trace.NewTask(context.Background(), "sumTask")
defer task.End() var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i ++ {
// 启动10个协程,只是做一个累加运算
go func(region string) {
defer wg.Done() // 标记region
trace.WithRegion(ctx, region, func() {
var sum, k int64
for ; k < 1000000000; k ++ {
sum += k
}
fmt.Println(region, sum)
})
}(fmt.Sprintf("region_%02d", i))
}
wg.Wait()
}

首先,代码的功能非常简单,只是启动10个协程,每个协程处理的工作都是一样的,即把0 ... 1000000000 做了sum 运算。

其次,代码中,添加了Task 和 Task 的Region,是我们更好的发现我们协程的位置(当然,我这里都捕获了,只是用Region 做了标识),并将记录的 trace 数据写入trace.dat 文件中。

最后,为了更好的看到协程对cpu的抢占,所以把cpu的个数限制为1个。

编译并运行,会得到如下结果:

# go build trace_example.go
# ./trace_example
region_09 499999999500000000
region_00 499999999500000000
region_01 499999999500000000
region_02 499999999500000000
region_03 499999999500000000
region_04 499999999500000000
region_05 499999999500000000
region_06 499999999500000000
region_07 499999999500000000
region_08 499999999500000000

从结果中,我们可以看出,协程执行的顺序不是那么有序。但是真实是怎么执行的呢?我们从 trace.dat 中获取答案。

Trace 分析

执行下面命令,打开trace 的web服务:

# go tool trace trace.dat
2020/04/16 17:34:09 Parsing trace...
2020/04/16 17:34:10 Splitting trace...
2020/04/16 17:34:10 Opening browser. Trace viewer is listening on http://127.0.0.1:53426

我们先从分析整个协程入手, 从这里可以看出,我们的协程其实没有按照时间片轮询的方式跑(毕竟这是一个纯计算性的工作)

而从Task中,我们观察所有自定义的Region 和goroutine.

从图中可以看出,task 任务所关注的region 是一个一个跑的,region_09 先执行了,这个也从我们的输出中得到了验证。从图中也可以看到,我们的goroutineid(G1, G10, G12 等, 虽然我们在go编写代码时并不能拿到这个goroutineid).

总结与反思

除了实操了一次 task 和 region 的自定义做trace 分析外,我们还能从这个例子中找到些什么信息。

  1. goroutine 肯定是存在的
  2. goroutine 的启动肯定不是有序的, 这一点从task 的图中就可以明显看出来
  3. goroutine 如果没有阻塞的服务的话,会一直占用cpu的(所以有了 runtime.Gosched() 的存在)

所以,对于一些占用高频cpu的服务(比如说加解密,编解码服务等)如果有别的优先级比较高的goroutine在工作,可以适当的让出CPU, 保证服务正常有序工作。

golang trace 分析 简例的更多相关文章

  1. Form_通过Trace分析Concurrent和Form性能和异常详解(案例)

    2014-06-21 Created By BaoXinjian

  2. linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client:clie ...

  3. 5.3linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...

  4. RabbitMQ消息可靠性分析 - 简书

    原文:RabbitMQ消息可靠性分析 - 简书 有很多人问过我这么一类问题:RabbitMQ如何确保消息可靠?很多时候,笔者的回答都是:说来话长的事情何来长话短说.的确,要确保消息可靠不只是单单几句就 ...

  5. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  6. 【MySQL 原理分析】之 Trace 分析 order by 的索引原理

    一.背景 昨天早上,交流群有一位同学提出了一个问题.看下图: 我不是大佬,而且当时我自己的想法也只是猜测,所以并没有回复那位同学,只是接下来自己做了一个测试验证一下. 他只简单了说了一句话,就是同样的 ...

  7. EBS trace分析

    下载Trace Analyzer,打开bin下的traceanalyzer.bat 即可分析EBS的trace文件,图形化界面,无需tkprof 需要配置javahome,确认java版本为1.6以上 ...

  8. PLSQL_性能优化效能跟踪工具SQL Trace分析(案例)

    2014-06-25 Created By BaoXinjian

  9. Hibernate内存溢出分析一例

    公司业务系统在进行压力测试时,压测24小时后系统发生内存溢出.经过分析读dump文件,发现org.hibernate.stat.StatisticsImpl类的hashmap类型的变量存储了大量数据( ...

随机推荐

  1. [UWP]抄抄《CSS 故障艺术》的动画

    1. 前言 什么是故障艺术(Glitch Art 风)?我们熟知的抖音的 LOGO 正是故障艺术其中一种表现形式.它有一种魔幻的感觉,看起来具有闪烁.震动的效果,很吸引人眼球.故障艺术它模拟了画面信号 ...

  2. shell编程之循环语句

    for #! /bin/sh for FRUIT in apple banana pear; do echo "I like $FRUIT" done while #! /bin/ ...

  3. pandas 的常用方法

    pandas的常用方法: 1.数据输入 2.数据查看 3.数据清洗 4.数据处理 5.数据提取 6.数据筛选 7.数据汇总 8.数据统计 9.数据输出 详情见: https://blog.csdn.n ...

  4. BFC是什么?BFC有什么用?看完全明白

    一.BFC是什么? 官方定义 BFC(Block Formatting Context,块格式化上下文) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交 ...

  5. Building Applications with Force.com and VisualForce (DEV401) 中用到的Recruiting Application介绍

    1.Who uses Recruiting Application. 2. Recruiting Application Object Model

  6. 使用Keras进行深度学习:(二)CNN讲解及实践

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 现今最主流的处理图像数据的技术当属深度神经网络了,尤其是卷积神经网 ...

  7. 记录一次MAC连接投影闪屏的问题。

    遇到的问题:MAC笔记本连接投影出现闪屏怎么办? 解决办法:尝试过很多种办法,后面发现这个闪屏原因是投影机的refresh rate 默认不支持这么高的.调整到30hz左右即可. 步骤:使用HDMI转 ...

  8. 【Springboot】实例讲解Springboot整合OpenTracing分布式链路追踪系统(Jaeger和Zipkin)

    1 分布式追踪系统 随着大量公司把单体应用重构为微服务,对于运维人员的责任就更加重大了.架构更复杂.应用更多,要从中快速诊断出问题.找到性能瓶颈,并不是一件容易的事.因此,也随着诞生了一系列面向Dev ...

  9. LeetCode(一) jump game

    一. 1. #include<iostream> #include<cmath> using namespace std; bool CanJump(int n[],int n ...

  10. docker 搭建keepalived+nginx高可用

    前言 最近工作 中 有用到keepalived,就想着 在 本地 搭建一套环境验证一下相关的功能.因为创建虚拟机比较麻烦,就借助  docker来搭建这样 一套 环境 ,顺带学习 巩固下docker的 ...