🚨 Alert không gây mệt mỏi

By Better Wise

3 giờ sáng, điện thoại rung. Màn hình hiện: "CPU 82%". Bạn mở laptop, hệ thống vẫn chạy bình thường. Hai mươi phút sau lại rung: "CPU 79%". Đến lần thứ năm thì bạn tắt thông báo. Từ đêm đó, alert không còn giá trị gì nữa.

Ở module trước, bạn đã có metric (latency, error rate) và một dashboard vài chỉ số đáng nhìn mỗi ngày. Alert là bước biến những con số đó thành tiếng gọi đúng lúc, đúng người. Sau bài này, bạn có thể:

  • Phân biệt alert theo triệu chứng người dùng và alert theo nguyên chân kỹ thuật bên trong
  • Viết điều kiện alert gồm ngưỡng và thời lượng for đủ dài
  • Nhận ra dấu hiệu alert fatigue và cách cắt bớt
  • Kiểm tra một alert có đủ thông tin để hành động lúc nửa đêm không

Alert nên bắt đầu từ triệu chứng người dùng

Người dùng không cảm nhận được CPU. Họ cảm nhận được: bấm nút thanh toán mà quay mãi, đăng nhập báo lỗi, trang mở chậm. Đó là triệu chứng. CPU, memory, số pod restart, dung lượng disk là nguyên nhân, và phần lớn nguyên nhân không ảnh hưởng gì tới người dùng.

Quy tắc đơn giản: page cho triệu chứng, xem dashboard cho nguyên nhân.

Tín hiệu Xử lý
Error rate 5xx > 2% trong 5 phút Page
p95 latency trang chủ > 1 giây trong 10 phút Page
Đăng nhập thất bại > 10% trong 3 phút Page
CPU 85% Dashboard
Một pod restart 2 lần Dashboard
Disk 70% Dashboard
flowchart TD
    User["👤<br/>Người dùng gặp lỗi"] --> Metric["📈<br/>Metric triệu chứng vượt ngưỡng"]
    Metric --> Dur{"⏱️<br/>Đúng liên tục đủ for?"}
    Dur -- Chưa --> Wait["Chờ tiếp"]
    Dur -- Rồi --> Alert["🚨<br/>Page on-call"]
    Alert --> Runbook["📘<br/>Runbook và dashboard"]

Bài tập 1. Trong bốn alert sau, cái nào nên page, cái nào chỉ để trên dashboard?

  1. Bộ nhớ của một worker chạm 78%
  2. Tỷ lệ lỗi thanh toán tăng lên 6% trong 5 phút
  3. Hàng đợi email có 2 job bị retry
  4. p95 latency trang chủ là 2,5 giây trong 10 phút

Xem gợi ý đáp án

Page: (2) và (4), vì người dùng đang bị ảnh hưởng trực tiếp. Dashboard: (1) và (3), vì đó là nguyên chân hoặc sự kiện nhỏ, chưa chắc ai cảm nhận được. Riêng (2) nên là alert nghiêm trọng nhất trong bốn cái.

Ngưỡng và thời lượng: cho alert thời gian để chắc chắn

Alert có hai tham số: ngưỡng (metric vượt bao nhiêu) và thời lượng (phải đúng liên tục bao lâu). Thiếu thời lượng, bạn có một cái chuông báo mỗi lần đường latency nhấp nhô, hiện tượng này gọi là flapping.

Warning: Đặt for quá ngắn biến alert thành máy đếm nhiễu. Một spike 30 giây thường không phải sự cố, và alert tự hết trước khi bạn kịp mở laptop còn tệ hơn không có alert.

Cách chọn nhanh: lỗi nghiêm trọng như thanh toán, đăng nhập thì for 3 đến 5 phút; lỗi nhẹ hoặc cảnh báo sớm thì 10 đến 15 phút, hoặc chỉ để trên dashboard.

Triệu chứng Ngưỡng Thời lượng
5xx error rate > 2% 5 phút
p95 latency trang chủ > 1 giây 10 phút
Đăng nhập thất bại > 10% 3 phút
Job nền thất bại > 5% 15 phút

Bài tập 2. Viết điều kiện alert cho luồng checkout, biết rằng bình thường tỷ lệ lỗi là 0,3% và mỗi giờ có khoảng 400 lượt thanh toán.

Xem gợi ý đáp án

Một đáp án hợp lý: "Tỷ lệ lỗi checkout > 2%, giữ liên tục 5 phút". Ngưỡng 2% cao hơn đường cơ sở 0,3% đủ xa để không rung khi có một hai giao dịch lỗi, nhưng vẫn thấp hơn mức người dùng bắt đầu bỏ đi. 5 phút đủ để loại spike tự hết. Đừng đặt ngưỡng 0,5%, vì gần như đêm nào cũng vượt.

Alert fatigue: khi thông báo nhiều hơn việc làm

Alert fatigue không phải là "người trực lười". Nó là phản ứng bình thường khi bị gọi sai quá nhiều lần: bạn bắt đầu bỏ qua, tắt tiếng, hoặc nhìn alert rồi tự nhủ "chắc lại CPU". Và đúng đêm có sự cố thật, bạn đọc nó như mọi thông báo nhiễu khác. Alert chỉ có giá trị khi nó dẫn tới một hành động.

Cách cắt nhiễu, làm theo thứ tự:

  1. Mỗi alert phải có hành động: không ai biết phải làm gì thì đó là dashboard, không phải page.
  2. Gộp alert cùng gốc: 20 alert "pod lỗi" của cùng một service là một sự cố, hãy alert theo tỷ lệ.
  3. Chỉ giữ hai mức: page và không page. Quá nhiều severity thì không ai nhớ mức nào cần dậy.
  4. Rà soát hàng tuần: alert nào 30 ngày không dẫn tới hành động thì xoá hoặc hạ xuống dashboard.

Bài tập 3. Một alert tên HighCPU, bắn khi CPU > 70% trong 1 phút, gửi vào kênh chat chung, không có runbook. Hãy sửa ba điểm.

Xem gợi ý đáp án

(1) Đổi từ nguyên chân sang triệu chứng, ví dụ error rate hoặc latency của service đó, hoặc nếu vẫn giữ CPU thì hạ xuống dashboard. (2) Tăng thời lượng lên 10 đến 15 phút. (3) Thêm runbook, owner và dashboard link, và chỉ gửi cho người trực thay vì cả công ty.

Một alert đủ tốt để hành động lúc 3 giờ sáng

Alert tồi

Tên: HighCPU Điều kiện: CPU > 70% trong 1 phút Hành động khi nhận: không rõ Kênh: chat chung của cả công ty Kết quả: mọi người tắt thông báo sau hai tuần

Alert tốt

Tên: TyLeLoiThanhToanCao Điều kiện: error rate của checkout > 2%, giữ liên tục 5 phút Severity: page Runbook: /runbooks/checkout-errors Dashboard: /d/checkout Owner: team payments Kết quả: người trực biết mở đâu, gọi ai, làm gì

Điền nhanh để nhớ:

Alert tốt bắt đầu từ _____ chứ không phải nguyên nhân kỹ thuật bên trong. Tham số for quyết định _____. Ngưỡng nên neo vào _____, không phải con số cảm tính. _____ là khi quá nhiều thông báo khiến người on-call bỏ qua cả alert thật. Alert không dẫn tới _____ thì nên đưa lên dashboard thay vì page. Chỉ nên page cho sự cố _____.

Thẻ ôn tập

Front: Alert nên dựa trên cái gì? Back: Triệu chứng người dùng cảm nhận, ví dụ error rate cao hoặc latency tăng, không dựa trên nguyên nhân như CPU.

Front: Tham số for trong alert dùng để làm gì? Back: Quy định điều kiện phải đúng liên tục bao lâu trước khi alert bắn.

Front: Vì sao alert CPU 85% thường không nên page? Back: CPU cao chưa chắc người dùng bị ảnh hưởng, nó là nguyên nhân và phù hợp để xem trên dashboard.

Front: Ngưỡng (threshold) là gì? Back: Giá trị mà metric phải vượt qua thì alert mới được xét tới.

Front: Flapping là gì? Back: Metric nhấp nhô quanh ngưỡng khiến alert bắn rồi tự hết liên tục.

Front: Alert fatigue là gì? Back: Quá nhiều alert khiến người on-call bỏ qua, tắt thông báo hoặc phản ứng chậm với sự cố thật.

Front: Dấu hiệu rõ nhất của một alert vô dụng? Back: Không ai làm gì sau khi nhận, hoặc alert tự hết trước khi có người xem.

Front: Một alert tốt cần tối thiểu thông tin nào? Back: Tên nói triệu chứng, điều kiện kèm thời lượng, severity, runbook, dashboard và owner.

Front: Alert 'chỉ để biết' nên đặt ở đâu? Back: Trên dashboard, không page.

Front: Vì sao nên gộp alert cùng gốc? Back: Nhiều alert giống nhau từ một service thực chất chỉ là một sự cố, gộp lạithành một alert theo service để người trực không bị ngập.

Chốt lại và bước tiếp theo

Ba câu để mang đi on-call:

  • Alert là để gọi người dậy, không phải để kể chuyện. Chỉ những gì đang ảnh hưởng người dùng mới đáng page.
  • Mọi alert đều cần đủ ba phần: ngưỡng, thời lượng, và hành động. Thiếu một trong ba thì đó là alert chưa xong.
  • Trước khi bật alert, tự hỏi: "Nếu cái này bắn lúc 3 giờ sáng, mình có dậy không?" Nếu câu trả lời là không, hạ nó xuống dashboard.

Một alert tốt là alert mà người trực đọc xong biết làm gì ngay, và mỗi tuần chỉ bắn vài lần. Bạn không cần nhiều alert, bạn cần đúng alert.

Bài tiếp theo sẽ đi sâu hơn một tầng: khi alert đã chỉ đúng "người dùng đang chậm ở luồng thanh toán", làm sao biết chậm ở bước nào trong chuỗi gọi giữa các service. Đó là lúc tracing ở mức khái niệm phát huy tác dụng, và nó nối rất tự nhiên với runbook bạn vừa viết.