goroutine 泄漏不一定忘了 cancel:还要看 sender 和 receiver 谁没回家
goroutine 泄漏最讨厌的地方,不是它会炸,而是它不炸。
它先是悄悄多几个,再多几十个,最后把内存、延迟、CPU 一起拖下水。你回头看日志,发现代码没报错;你再看监控,发现曲线只是在往上爬。
很多人看到这种情况,第一反应是:是不是忘了 …
goroutine 泄漏最讨厌的地方,不是它会炸,而是它不炸。
它先是悄悄多几个,再多几十个,最后把内存、延迟、CPU 一起拖下水。你回头看日志,发现代码没报错;你再看监控,发现曲线只是在往上爬。
很多人看到这种情况,第一反应是:是不是忘了 …
goroutine 从 200 慢慢涨到 2 万,线上服务还没挂,但你知道它不对劲。
监控图上那条线不陡,甚至有点温和。它不像事故,更像一个迟早会来的事故。
这时候很多人的第一反应是:把 channel buffer 调大一点。 …
服务又 OOM 了。
Pod 刚重启,群里已经开始出方案:GOMEMLIMIT 设低一点,GOGC 调一下,limit 先加 1Gi,GC 日志再翻一遍。
这些动作有时候能救火,但经常救不到根上。
因为很多 Go 服务所谓的“内存泄漏”,根 …
服务又被 OOMKilled 了。
Pod 刚重启,群里已经开始报菜名:把 GOGC 调低一点,给 GOMEMLIMIT 设个值,容器 limit 再加 1Gi,顺手翻一下 GC 日志。
这些动作不一定错,但顺序错了。
你现在看到的是“尸体 …
上篇讲完 GOGC、GOMEMLIMIT 和 STW,很多人真正卡住的地方才刚开始。
不是“不知道这些参数是什么”,而是线上真的出问题时,不知道下一步该干什么。
服务 p99 每隔几十秒抖一下,GC CPU 看起来有 5%。有人说把 …
pprof 抓回来了,最容易发生的事不是你看不懂。
而是你看懂了一半:知道一批 goroutine 卡在 main.worker,知道等待状态是 [chan receive],知道创建点也在栈里,可下一步还是开始全局搜 context、搜 …
线上 goroutine 数开始往上爬,很多人的第一反应是猜。
是不是 context 泄漏?是不是超时没生效?是不是某个 channel 没人读?是不是锁没释放?
这些猜法都可能对。
但问题在于,你现在还没有证据。你只有一个数字 …
接口已经超时了,goroutine 曲线还在往上爬。
上篇讲到这里时,我们先压住了一个误判:这通常不是 context 没生效,而是你的 goroutine 没有响应取消信号。
但还有一个更隐蔽的问题,很多 Go 代码每天都在写:
|
服务又被 OOMKilled 了。
Pod 刚重启,群里已经有人开始翻 GC 日志。有人说 GC CPU 到了 20%,有人说把 GOGC 调低一点,还有人建议直接上 GOMEMLIMIT。
这些动作不一定错,但顺序错了。 …
服务内存从 800MB 慢慢涨到 2.6GB。
曲线不陡,不像雪崩。它只是每天往上爬一点,重启以后掉下来,过几天又回到老地方。告警响了,群里第一句话通常是:是不是内存泄漏?
这个判断不算错,但太急。
在 Go 服务里,内存持续上涨可能是真泄 …
goroutine 数量从 200 慢慢涨到 2 万。
监控图上那条线,不陡,但一直在爬。就像水龙头没拧紧——不喷,但也不会停。
你的第一反应是什么?
加大 buffer。
make(chan int, 100) 改成 make(chan …
线上 goroutine 数开始往上爬,最怕的不是它涨。
最怕的是你盯着监控看了十分钟,然后开始猜:是不是 context 泄漏了?是不是超时没生效?是不是某个 channel 卡住了?
这些猜法都有可能对,也都有可能错。 …