golang协程泄漏排查实战

问题背景

某个周末,线上实例开始偶发cpu利用率到达80%的报警,且当时业务几乎无流量,个别实例的cpu利用率仍居高不下

业务是处理websocket的长连接,在请求结束时会通过channel的关闭事件通知各协程退出

排查过程

  1. 首先通过pprof命令采集了一段时间的cpu时间的占用情况,发现大量时间被运行时的协程调度占用,但当时已无流量,所以这种占用情况是不符合预期的
  2. 通过以下命令拉取当时存活的协程
bash 复制代码
curl http://localhost:6790/debug/pprof/goroutine?debug=2 > goroutines.txt
less goroutines.txt
grep yourFunc goroutines.txt

详细的pprof命令可以参考这里

分析过程

其中存活的协程分为以下两部分

  1. hertz, mertrics这些长期存活的和服务监听或者是监控上报有关,本身监控或者对端口的监听会持续存在,这部分没问题。
  2. 另一部分是少量的业务处理过程中开辟的协程,这部分应该随着请求的结束而推出,但实际并没有,问题看来就出现在了这里,因为大量协程没有退出导致调度成本越来越大

解决方案

当前程序对于开辟的协程管理十分不严谨,是通过在各协程中感知channel的close行为然后自行退出,并且关闭channel的行为仅发生在处理请求的过程中。将其修改为go自带的context管理,感知context的cancel行为,将原来对channel的关闭替换为对cancel的调用,并且在websocket被对端关闭的情况下调用cancel。

上线观察几天后,cpu利用率下降,之后继续观察线上问题是否彻底缓解

相关推荐
脚踏实地皮皮晨12 分钟前
003006001_WrapPanel控件
开发语言·c#·.net·wpf·visual studio
上海安当技术34 分钟前
单点登录 SSO 怎么选协议?SAML 2.0 / OAuth 2.0 / OIDC / CAS 对比与 ERP、OA、CRM 接入实战
java·开发语言
不才不才不不才1 小时前
Spring 源码系列(14): JDK 动态代理 vs CGLIB,以及拦截器责任链
java·开发语言·spring
mifengxing1 小时前
计算机组成原理——存储器系统
开发语言·考研·计算机组成原理·复习笔记·计算机408
山水洛行1 小时前
都在聊Context Engineering图工程,可你说的图和他说的不是一个图
后端
Yao8061 小时前
MinIO自建对象存储,省OSS费用的完整方案
前端·后端
Ai拆代码的曹操1 小时前
深夜告警风暴:Dubbo 异步调用回调丢失 300 次——一个 tech lead 的自述
后端·dubbo
Yolanda_20222 小时前
Python学习-第九部分-错误处理与异常处理
开发语言·python·学习
郝学胜-神的一滴2 小时前
Qt 高级编程 037:QSS按钮样式封神指南
开发语言·c++·qt·软件工程·用户界面
DFT计算杂谈2 小时前
SCIENTIFIC REPORTS 非 van der Waals可调二维磁性材料设计平台
开发语言·php