Lập trình Go 22/09/2026 11 phút

Metrics với Prometheus client trong Go: counter, gauge, histogram và chi phí đo

Trace chẩn đoán một request; metrics trả lời hệ thống có khỏe không. Bài mổ xẻ ba loại metric Prometheus trong Go, vì sao histogram hơn hẳn trung bình, và đo thật chi phí: mọi thao tác 0 cấp phát, nhưng WithLabelValues tra cứu nhãn tốn 24 ns mỗi lần — cache handle về 1.7 ns.

Lập trình 22/09/2026 7 phút

Counter và gauge với expvar: hai loại metric nền tảng, và vì sao đếm không atomic mất 80% dữ liệu

Log trả lời 'chuyện gì đã xảy ra với request này', metric trả lời 'hệ thống đang thế nào tổng thể'. Bài này đo thật hai loại metric cơ bản nhất bằng expvar của thư viện chuẩn Go: counter (tổng cộng dồn, chỉ tăng) và gauge (mức tức thời, lên xuống). Kèm một bằng chứng đanh thép về tính đồng thời: 50 goroutine cùng ++ một biến int thường làm mất 81.9% số đếm, trong khi expvar.Int (atomic) đếm đúng tuyệt đối.

Lập trình 22/09/2026 7 phút

Histogram và percentile: vì sao latency trung bình 45ms là lời nói dối, và p99 mới là sự thật

Sếp hỏi 'API nhanh không?', bạn trả lời 'trung bình 45ms'. Cả hai đều sai lầm — vì không ai trải nghiệm cái trung bình đó. Bài này đo thật trên 100.000 mẫu latency lệch: mean 44.9ms nhưng p50 chỉ 15.3ms và p99 tới 725ms — trung bình rơi vào khoảng trống không ai gặp. Kèm cách dựng histogram kiểu Prometheus để ước lượng percentile với O(1) bộ nhớ, và đo thẳng sai số của nó (p95 lệch tới -34%).

Lập trình 22/09/2026 7 phút

Prometheus client trong Go: expose /metrics, đọc định dạng exposition, và hiểu mô hình pull

expvar cho counter/gauge nhưng thiếu label và histogram — production cần nhiều hơn. Bài này đo thật với thư viện Prometheus client_golang: khai CounterVec (label method/status) và HistogramVec, tung 1000 request, rồi curl /metrics đọc output thật. Xem histogram tự sinh _bucket{le=...}/_sum/_count ra sao, kiểm số liệu khớp tải bằng grep, và hiểu vì sao Prometheus scrape (pull) thay vì nhận push.

Lập trình 22/09/2026 7 phút

RED và USE: hai phương pháp chọn đúng metric, để khỏi đo tràn lan mà vẫn mù lúc sự cố

Có công cụ metric rồi, câu hỏi khó hơn là ĐO CÁI GÌ. Đo tràn lan làm loãng tín hiệu và nổ cardinality; đo thiếu thì mù lúc sự cố. Hai phương pháp luận cắt gọn: RED (Rate, Errors, Duration) cho service, USE (Utilization, Saturation, Errors) cho tài nguyên. Bài này đo thật một service worker-pool ở tải thấp và tải cao: RED cho thấy lỗi nhảy từ 1.5% lên 6.9%, còn USE chỉ đúng nguyên nhân — pool utilization 100%, queue dồn tới 18, 103 request bị từ chối.

Lập trình 22/09/2026 6 phút

Cardinality explosion: một label user_id làm nổ metric store 2000 lần — nguyên nhân số 1 sập Prometheus

Label làm metric mạnh lên (cắt lát theo method, status), nhưng đặt sai một label là tự tay cho nổ. Bài này đo thật với client_golang: cùng một counter, label an toàn {method, status} sinh 10 chuỗi thời gian; thêm một label user_id thành 20.000 chuỗi — nổ đúng 2000 lần. Vì cardinality là TÍCH số giá trị mọi label, không phải tổng; và user_id/request_id/URL trong thực tế là vô hạn, chuỗi tăng không ngừng tới khi Prometheus ngốn hết RAM và sập.