- #go
- #concurrency
- #goroutine-leak
- #context
- #production
Sai lầm Go khiến production sập: rò rỉ goroutine và context bị bỏ quênCommon Go pitfalls that crash production: goroutine leaks and forgotten contexts
Giới thiệu các nguyên nhân gây rò rỉ goroutine và cách dùng context đúng để tránh crash trong môi trường production.Explain why goroutine leaks happen, how missing context leads to failures, and show practical fixes for production Go services.

Mục lụcContents· 9
Bạn có bao giờ deploy một service Go, rồi sau vài giờ nhận được cảnh báo CPU 100 % và pod bị kill? Thông thường nguyên nhân không phải query chậm mà là một goroutine leak: một hoặc nhiều goroutine vẫn chạy vô hạn vì không nhận được tín hiệu dừng. Khi cùng lúc thiếu context trong các hàm bất đồng bộ, bạn còn có nguy cơ deadlock hoặc dữ liệu cũ bị xử lý sau khi request đã trả lời. Trong bài này mình sẽ phân tích hai lỗi thường gặp, minh họa bằng code thực tế, rồi đưa ra các biện pháp phòng ngừa để hệ thống không bị sập.
Nguyên nhân thường gặp#
Rò rỉ goroutine khi không có cancel#
Trong Go, việc tạo goroutine là rất nhẹ, nhưng nếu không có cơ chế hủy (cancel) hoặc không đóng kênh (channel) mà goroutine đang chờ, nó sẽ tiếp tục chạy mãi. Ví dụ, một hàm đọc tin nhắn từ Kafka trong một vòng lặp vô hạn, nhưng không kiểm tra ctx.Done(). Khi pod được shutdown, goroutine vẫn còn “đang ngủ” trên select và không được dừng, dẫn tới tăng dần số lượng goroutine và tiêu tốn tài nguyên.
func consume(ctx context.Context, msgs <-chan Message) {
for {
select {
case m := <-msgs:
// Xử lý tin nhắn
handle(m)
case <-time.After(5 * time.Second):
// timeout, tiếp tục vòng lặp
}
// LỖI: không kiểm tra ctx.Done()
}
}