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

作者:zoudaohoutianI 时间:2024-05-08 10:22:09 

一、前言

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

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

通过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,如下图所示:

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

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

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

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

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

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

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

如下图所示:

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

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

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

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

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

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

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

来源:https://blog.csdn.net/zoudaohoutianI/article/details/127030389

标签:go,cpu过高,排查
0
投稿

猜你喜欢

  • python语言是免费还是收费的?

    2021-12-30 10:04:48
  • PHP延迟静态绑定使用方法实例解析

    2024-06-05 15:41:45
  • 如何往SQL Server数据库传递日期数据?

    2010-06-08 09:29:00
  • js三维正方体(兼容ie/ff)

    2008-04-12 14:38:00
  • WAP设计基础

    2011-01-06 12:13:00
  • 显示某日期所在星期的所有日期asp代码

    2008-06-01 16:05:00
  • python如何发送带有附件、正文为HTML的邮件

    2022-05-22 08:15:15
  • ACCESS入门教程:窗口和菜单的使用

    2008-01-03 20:15:00
  • Scrapy爬虫文件批量运行的实现

    2022-04-25 18:29:57
  • javascript cookies 设置、读取、删除实例代码

    2024-04-19 10:01:51
  • colab中修改python版本的全过程

    2022-10-31 07:18:38
  • 利用Pycharm断点调试Python程序的方法

    2023-07-05 03:47:08
  • python 并发下载器实现方法示例

    2022-03-31 10:46:00
  • django框架模板中定义变量(set variable in django template)的方法分析

    2021-11-18 03:28:04
  • Python正则表达式re.search()用法详解

    2021-08-28 03:24:46
  • 利用MySQL空间函数实现位置打卡的完整步骤

    2024-01-28 11:23:32
  • Python接口自动化判断元素原理解析

    2022-09-04 18:33:58
  • ACCESS入门教程:用向导建立数据库

    2008-01-17 12:46:00
  • 在Ubuntu 20.04中安装Pycharm 2020.1的图文教程

    2022-05-28 23:03:48
  • Idea开发工具之SpringBoot整合JSP的过程

    2023-06-14 19:50:23
  • asp之家 网络编程 m.aspxhome.com