go语言程序cpu过高问题排查的方法详解

 更新时间:2023年04月15日 16:18:34   作者:zoudaohoutianI  
使用golang进行复杂的组合运算,导致CPU占用率非常高,下面这篇文章主要给大家介绍了关于go语言程序cpu过高问题排查的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

一、前言

Go程序像C/C++一样,如果开发编码考虑不当,会出现cpu负载过高的性能问题。如果程序是线上环境或者特定场景下出现负载过高,问题不好复现,则需要利用当前负载过高的进程进行调用栈分析。

C/C++中一般先通过top -d 1 -p $pid -H 命令查看负载过高的线程号(TID),然后使用gdb attach到该进程,通过thread info获取线程信息,然后切换到对应负载高的线程,输入bt查看调用栈。

结合对应代码中的函数,进一步分析。Go语言中方法也类似,我们将通过dlv来分析负载高的协程调用栈。

二、问题排查过程

2.1 通过top查看高cpu的进程pid

通过top -d 1,可以发现进程cava_smu(pid=11205)的cpu过高。

2.2 通过top查看高cpu的线程tid

通过上一步,我们确定了是pid=11205的cava_smu进程cpu过高,那么可以通过top -d 1 -p 11205 -H 来确认cpu过载的线程tid,如下图所示:

通过以上操作,可以确认tid=11208,11212,11213三个线程的cpu过高。

2.3 通过dlv附加到进程,分析线程/协程cpu过载的堆栈

首先,如果生产环境没有dlv,则可以拷贝对应的dlv到/usr/local/bin下。

接着 dlv attach 11205,确认tid=11208的goroutine 序号,如下图所示:

2.4 在dlv中切换到对应高cpu协程,并查看堆栈

如下图所示:

通过以上操作,可以确认业务底层的栈帧是第6→5帧,business.go:18行的disPatchTask ->business.go:168 行的dispatchIdleTeu方法相关,查看对应版本代码如下:

代码执行到下图中,dispatchIdleTeu返回了错误qferror.ErrNoTeu。

代码执行到下图中,189行dispatchIdleTeu返回了错误qferror.ErrNoTeu,所以189 if的执行语句192~212无法进入进行,而外层是一个for死循环,则会造成该协程一直占用cpu,导致cpu过载。

修复方法可以是在for 循环内增加sleep休眠,例如在214行处增加time.Sleep(200 * time.Millisecond),效果请自行验证。

总结

到此这篇关于go语言程序cpu过高问题排查的文章就介绍到这了,更多相关go程序cpu过高排查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go 1.18新特性之泛型的全面讲解

    Go 1.18新特性之泛型的全面讲解

    本文力求能让未接触过泛型编程的人也能较好理解Go的泛型,所以行文可能略显啰嗦。但是请相信我,看完这篇文章你能获得对Go泛型非常全面的了解
    2023-03-03
  • 详解golang碎片整理之 fmt.Scan

    详解golang碎片整理之 fmt.Scan

    本文介绍了从golang语言中fmt包从标准输入获取数据的Scan系列函数、从io.Reader中获取数据的Fscan系列函数以及从字符串中获取数据的Sscan系列函数的用法,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • Golang实现自定义时间结构体并支持Json&Gorm

    Golang实现自定义时间结构体并支持Json&Gorm

    因为时区等问题,很多项目需要自定义时区和时间格式,所以这篇文章主要为大家介绍了Golang如何实现自定义时间结构体并支持Json&Gorm,希望对大家有所帮助
    2024-03-03
  • 模块一 GO语言基础知识-库源码文件

    模块一 GO语言基础知识-库源码文件

    这篇文章主要介绍了模块一 GO语言基础知识-库源码文件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • goland -sync/atomic原子操作小结

    goland -sync/atomic原子操作小结

    这篇文章主要介绍了goland -sync/atomic原子操作,原子操作能够保证执行期间是连续且不会被中断(变量不会被其他修改,mutex可能存在被其他修改的情况),本文给大家介绍的非常详细,需要的朋友参考下
    2022-08-08
  • Mac上Go环境和VS Code的正确安装与配置方法

    Mac上Go环境和VS Code的正确安装与配置方法

    Go语言是一个新兴的语言。下面介绍一下如何在Mac系统下安装和使用这个语言,Go语言提供了mac下安装包,可直接下载安装包点击安装
    2018-03-03
  • go logger不侵入业务代码使用slog替换zap并实现callerSkip详解

    go logger不侵入业务代码使用slog替换zap并实现callerSkip详解

    这篇文章主要为大家介绍了go logger不侵入业务代码使用slog替换zap并实现callerSkip详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 解决go在函数退出后子协程的退出问题

    解决go在函数退出后子协程的退出问题

    这篇文章主要介绍了解决go在函数退出后子协程的退出问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • golang复用http.request.body的方法示例

    golang复用http.request.body的方法示例

    这篇文章主要给大家介绍了关于golang复用http.request.body的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-10-10
  • golang压缩与解压缩文件的示例代码

    golang压缩与解压缩文件的示例代码

    这篇文章主要给大家介绍了golang压缩与解压缩文件,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02

最新评论