go 定时器泄漏,导致 CPU占用高
·
问题
服务器长期开着,遇到一个问题,没有几个有效负载,CPU 占用了 2 个核
go tool pprof 了下,大致如下调用消耗:

top100 ,显示 runtime.siftdownTimer 占了大头(2 个图,取至不同服务)

问题分析
可以看到,均为定时器相关代码调用
review 代码,不少定时器用完没有 Stop 释放
模拟做下类似情景性能测试:
1. 创建 2w 个 timer + 1 个 timer 在工作:
如图,CPU 占用了 61.5%
2. 只有 1 个 timer 在工作
看不到 CPU 消耗
因此可以得出结论:定时器泄漏,会导致 CPU 占用高
为什么会消耗 CPU
参考 https://www.cnblogs.com/Zereker/p/11396639.html
该作者分析的很透彻了
再做个试验
把泄漏的定时器,时间间隔改大到秒级别。单个定时器工作时,CPU也不会上去
因此,要避免同时存在大量毫秒级别的定时器,golang 底层需要维护优先队列数据结构会消耗大量 CPU
因为最坏的操作,每次维护优先队列数据结构都是 O(LogN) 的时间复杂度。而大量毫秒级别的定时器会把时间复杂度拉到最坏情况 O(M*LogN)
golang 定时器问题总汇
到目前为止,至少遇到 3 处 golang 定时器问题,及解决方案:
| 定时器问题 | 解决方案 |
|---|---|
| 定时器泄漏 | 避免内存泄漏,比如可以封装 timer ,引用计数,随意可以查看定时器对象数量等 |
| 同时刻存在大量毫秒级定时器 | 业务上要避免这种情况的代码,没有通用解决方案 |
| session 级别秒级定时器 | 业务上做到被动触发,来规避该问题 |
参考
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)