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过高排查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang 项目打包部署环境变量设置方法

    golang 项目打包部署环境变量设置方法

    最近将 golang 项目打包部署在不同环境,下面分享一下我的心得体会,对golang 项目打包部署环境变量设置方法感兴趣的朋友一起看看吧
    2024-07-07
  • Golang中闭包与常用场景详解

    Golang中闭包与常用场景详解

    在很多的开源项目里,经常看到闭包的运用,这篇文章主要为大家简要记录一下闭包的概念和一些常用的场景,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • GO语言结构体面向对象操作示例

    GO语言结构体面向对象操作示例

    这篇文章主要介绍了GO语言编程中结构体面向对象的操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • 浅析GO语言的垃圾回收机制

    浅析GO语言的垃圾回收机制

    今天我们来聊聊golang是如何进行垃圾回收的,我们知道,目前各语言进行垃圾回收的方法有很多,如引用计数、标记清除、分代回收、三色标记等,各种方式都有其特点,文中介绍的非常详细,感兴趣的小伙伴跟着小编一起学习吧
    2023-07-07
  • GO语言协程互斥锁Mutex和读写锁RWMutex用法实例详解

    GO语言协程互斥锁Mutex和读写锁RWMutex用法实例详解

    这篇文章主要介绍了GO语言协程互斥锁Mutex和读写锁RWMutex用法详解,需要的朋友可以参考下
    2022-04-04
  • go内存缓存BigCache实现BytesQueue源码解读

    go内存缓存BigCache实现BytesQueue源码解读

    这篇文章主要为大家介绍了go内存缓存BigCache实现BytesQueue源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • golang gorm开发架构及写插件示例

    golang gorm开发架构及写插件示例

    这篇文章主要为大家介绍了golang gorm开发架构及写插件的详细示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • victoriaMetrics库布隆过滤器初始化及使用详解

    victoriaMetrics库布隆过滤器初始化及使用详解

    这篇文章主要为大家介绍了victoriaMetrics库布隆过滤器初始化及使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go语言排序算法之插入排序与生成随机数详解

    Go语言排序算法之插入排序与生成随机数详解

    从这篇文章开始将带领大家学习Go语言的经典排序算法,比如插入排序、选择排序、冒泡排序、希尔排序、归并排序、堆排序和快排,二分搜索,外部排序和MapReduce等,本文将先详细介绍插入排序,并给大家分享了go语言生成随机数的方法,下面来一起看看吧。
    2017-11-11
  • Go语言带缓冲的通道的使用

    Go语言带缓冲的通道的使用

    Go语言中有缓冲的通道是一种在被接收前能存储一个或者多个值的通道,本文就来介绍一下Go语言带缓冲的通道的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01

最新评论