Goroutine 泄漏是 Go 服务内存持续增长的常见根因:启动的协程因阻塞在 channel 发送/接收或无限循环中永不退出。通过 context.Context 的取消信号传播,配合 select 监听 ctx.Done(),可确保协程树级联退出。
一、Context 取消与 select 退出模式
go
func worker(ctx context.Context, jobs <-chan Job) {
for {
select {
case <-ctx.Done():
// 收到取消信号,立即退出,避免 Goroutine 泄漏
return
case job, ok := <-jobs:
if !ok {
return
}
process(job)
}
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
go worker(ctx, jobs)
}