Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng: 2 giờ sáng, điện thoại bạn rung liên hồi. Một tin nhắn PagerDuty hiện lên: "API checkout trả về lỗi 500, tỷ lệ lỗi 42%". Ngoài kia khách hàng đang không thanh toán được, mỗi phút hệ thống down là doanh thu bốc hơi và niềm tin sứt mẻ. Bạn — đang ngái ngủ — chính là người duy nhất giữa sự cố và thảm họa. Đó là on-call.
On-call (trực hệ thống) và incident response (ứng phó sự cố) là nơi mọi thứ bạn học trong khóa này — monitoring, alerting, IaC, Kubernetes — được kiểm chứng dưới áp lực thật. Một hệ thống được thiết kế tốt đến đâu cũng sẽ có lúc hỏng. Câu hỏi không phải "có sự cố hay không" mà là "khi sự cố xảy ra, đội của bạn phản ứng nhanh và có kỷ luật đến mức nào".
Ở Việt Nam, nhiều đội DevOps mới lập vẫn xử lý sự cố theo kiểu "ai rảnh thì sửa", không có lịch trực rõ ràng, không có escalation, và người giỏi nhất thì kiệt sức vì bị gọi lúc nào cũng được. Bài này giúp bạn xây dựng một hệ thống on-call chuyên nghiệp, nhân văn và hiệu quả — nơi sự cố được xử lý nhanh mà con người không bị vắt kiệt.
Khái niệm cốt lõi
On-call là gì và vì sao cần có kỷ luật
On-call là cơ chế đảm bảo luôn có người chịu trách nhiệm phản hồi khi hệ thống gặp vấn đề, kể cả ngoài giờ hành chính. Điểm mấu chốt: on-call không phải là "trực để sửa mọi thứ", mà là "trực để đảm bảo sự cố được ghi nhận, đánh giá và điều hướng đúng người trong thời gian cam kết".
Một hệ thống on-call tốt cần trả lời được ba câu hỏi: Ai đang trực? Nếu người đó không phản hồi thì ai tiếp theo? Và làm sao để người trực không bị quá tải đến mức nghỉ việc?
Mô hình phân tầng on-call
Đây là xương sống của on-call chuyên nghiệp, gồm ba tầng:
Primary (người trực chính) — first responder. Đây là người đầu tiên nhận alert. Trách nhiệm của primary là acknowledge (xác nhận đã thấy) alert trong một khoảng thời gian cam kết — thường 5 phút với sự cố nghiêm trọng — rồi bắt đầu điều tra hoặc điều hướng.
Secondary (người trực dự phòng) — backup. Nếu primary không acknowledge trong X phút (ví dụ 5–10 phút), hệ thống tự động escalate sang secondary. Secondary cũng hỗ trợ khi sự cố quá lớn, một người không kham nổi. Đây là lưới an toàn tránh trường hợp primary ngủ quên, mất sóng, hoặc điện thoại hết pin.
Manager escalation (leo thang lên quản lý) — sau Y phút mà cả primary lẫn secondary đều không phản hồi, hoặc sự cố vượt quá thẩm quyền kỹ thuật (cần quyết định business, cần thông báo khách hàng, cần huy động nhiều đội), alert sẽ leo lên engineering manager hoặc trưởng nhóm. Manager không nhất thiết sửa lỗi kỹ thuật, mà điều phối nguồn lực và ra quyết định.
Chuỗi escalation này chính là ý cốt lõi trong ghi chú gốc: Primary → Secondary → Manager, với mốc thời gian rõ ràng ở mỗi bước. Không có mốc thời gian, escalation chỉ là lý thuyết.
Severity — phân loại mức độ nghiêm trọng
Không phải sự cố nào cũng đáng gọi bạn dậy lúc 2 giờ sáng. Đội chuyên nghiệp phân loại severity (thường viết tắt SEV):
- SEV-1 (Critical): hệ thống chính không dùng được, ảnh hưởng phần lớn khách hàng, mất doanh thu. Phải phản hồi ngay lập tức, 24/7. Ví dụ: toàn bộ trang thanh toán sập.
- SEV-2 (Major): một tính năng quan trọng lỗi nhưng có workaround, hoặc suy giảm hiệu năng đáng kể. Phản hồi trong giờ, có thể chờ đến sáng nếu ngoài giờ.
- SEV-3 (Minor): lỗi nhỏ, ít người ảnh hưởng, không khẩn cấp. Xử lý trong giờ làm việc như task thường.
Incident Commander — vai trò điều phối
Khi sự cố lớn (SEV-1), việc "ai cũng nhảy vào gõ lệnh" gây hỗn loạn. Mô hình Incident Command System (mượn từ đội cứu hỏa) chỉ định một Incident Commander (IC) — người điều phối, không nhất thiết là người giỏi kỹ thuật nhất. IC không sửa lỗi; IC giữ nhịp cuộc họp xử lý, phân công (ai điều tra database, ai đọc log, ai cập nhật khách hàng), và ra quyết định. Bên cạnh IC thường có Scribe (ghi lại timeline) và Communications Lead (cập nhật status page, thông báo nội bộ).
Runbook — kịch bản xử lý
Runbook là tài liệu hướng dẫn từng bước xử lý một loại sự cố cụ thể: triệu chứng, cách chẩn đoán, các lệnh cần chạy, cách rollback. Runbook tốt biến một sự cố đáng sợ lúc 2 giờ sáng thành việc làm theo checklist. Mỗi alert nên có link tới runbook tương ứng.
Tình huống thực tế
Ví dụ 1 — Sàn TMĐT "ShopViet" và sự cố Flash Sale 12/12
ShopViet (công ty giả định mô phỏng các sàn TMĐT Việt Nam) chạy chương trình sale lớn ngày 12/12. Lúc 21:15, khi lượng truy cập đạt đỉnh 80.000 người dùng đồng thời, service giỏ hàng bắt đầu trả lỗi timeout. Alert page tới Primary là bạn Minh.
Minh acknowledge sau 3 phút, mở runbook "Cart service high latency". Runbook chỉ ra bước đầu tiên: kiểm tra connection pool tới database. Đúng như dự đoán, pool đã cạn — service không mở đủ kết nối cho lượng traffic tăng đột biến. Minh nhận ra đây là SEV-1, vượt khả năng xử lý một mình, nên chủ động escalate sang Secondary là chị Lan và ping manager để kích hoạt quy trình sự cố.
Chị Lan đóng vai Incident Commander, phân công: Minh scale connection pool và thêm read replica, một bạn khác bật cache tạm cho trang giỏ hàng, còn Communications Lead cập nhật banner "hệ thống đang tải cao" cho khách. Sau 22 phút, hệ thống ổn định trở lại.
Bài học: Escalation không phải dấu hiệu yếu kém — Minh chủ động leo thang khi biết mình không kham nổi là hành động đúng. Runbook giúp chẩn đoán trong vài phút thay vì mò mẫm. Và việc tách vai trò (IC điều phối, engineer sửa lỗi, comms nói với khách) giữ cho cuộc xử lý không hỗn loạn.
Ví dụ 2 — Fintech "PayNhanh" và bài học escalation gãy
PayNhanh (fintech giả định) có lịch on-call nhưng escalation policy cấu hình sai. Một đêm, service đối soát giao dịch bị treo. Alert page tới Primary là bạn Tuấn — nhưng Tuấn đang ở vùng sóng yếu khi về quê, điện thoại không nhận được cuộc gọi. Đáng lẽ sau 10 phút phải escalate sang Secondary, nhưng vì cấu hình PagerDuty thiếu bước secondary, alert cứ lặp lại tới Tuấn suốt 40 phút mà không ai khác được báo.
Đến khi một khách hàng doanh nghiệp gọi hotline phàn nàn, đội mới biết. Tổng thời gian phát hiện (MTTA — mean time to acknowledge) lên tới gần một tiếng, thay vì mục tiêu 5 phút. Giao dịch của nhiều merchant bị treo, gây thiệt hại uy tín.
Sau sự cố, PayNhanh làm postmortem và sửa ba thứ: (1) thêm tầng Secondary và Manager escalation với mốc 10 phút và 20 phút; (2) yêu cầu người trực xác nhận có sóng và pin trước ca; (3) thêm alert phụ báo lên kênh Slack chung nếu không ai acknowledge sau 15 phút.
Bài học: Một chuỗi escalation chỉ mạnh bằng mắt xích yếu nhất. Thiếu tầng Secondary biến cả hệ thống on-call thành vô dụng khi Primary không phản hồi. Escalation phải được test định kỳ, không phải cấu hình một lần rồi tin là nó chạy.
Ví dụ 3 — Startup SaaS và cái giá của alert fatigue
Một startup SaaS ở TP.HCM với đội 6 kỹ sư đặt alert cho gần như mọi thứ: CPU trên 70%, mỗi lỗi 4xx đơn lẻ, disk trên 60%. Kết quả là người trực nhận trung bình 30–40 page mỗi đêm, hầu hết là nhiễu. Sau vài tuần, các kỹ sư bắt đầu "phản xạ acknowledge rồi ngủ tiếp" mà không đọc — hiện tượng alert fatigue (mệt mỏi vì cảnh báo).
Rồi thảm họa đến: một alert thật về việc database sắp hết dung lượng bị lẫn trong đống nhiễu và bị bỏ qua. Database đầy, hệ thống ghi dữ liệu thất bại suốt 3 tiếng.
Đội xử lý bằng cách rà lại toàn bộ alert theo nguyên tắc "mỗi page phải actionable và khẩn cấp". Họ hạ 70% alert xuống mức chỉ ghi log/dashboard chứ không page, gộp các alert liên quan, và thêm ngưỡng thời gian (chỉ page nếu CPU cao liên tục 10 phút). Số page ban đêm giảm còn 2–3 lần mỗi tuần.
Bài học: On-call bền vững phụ thuộc vào chất lượng alert. Quá nhiều alert còn nguy hiểm hơn quá ít, vì nó huấn luyện con người phớt lờ. Bảo vệ giấc ngủ của người trực chính là bảo vệ độ tin cậy hệ thống.
Hướng dẫn từng bước
Đây là lộ trình xây dựng hệ thống on-call cho đội của bạn:
Bước 1 — Lập lịch xoay ca (rotation). Dùng công cụ như PagerDuty, Opsgenie, hoặc Grafana OnCall. Chia ca theo tuần là phổ biến (một người trực Primary 7 ngày rồi chuyển). Với đội nhỏ, đảm bảo ít nhất 4–6 người trong vòng xoay để mỗi người chỉ trực khoảng một lần mỗi tháng — tránh kiệt sức.
Bước 2 — Thiết lập escalation policy. Cấu hình rõ: Primary có 5 phút để acknowledge → nếu không, escalate Secondary → sau 10 phút nữa, escalate Manager. Ghi rõ mốc thời gian bằng con số, đừng để mơ hồ.
Bước 3 — Phân loại severity và định nghĩa cái gì được page. Chỉ SEV-1 và SEV-2 khẩn mới đánh thức người ngoài giờ. Mọi thứ khác vào hàng đợi xử lý giờ hành chính.
Bước 4 — Viết runbook cho các sự cố phổ biến. Mỗi alert quan trọng phải kèm link runbook: triệu chứng, lệnh chẩn đoán, cách khắc phục, cách rollback, khi nào cần escalate.
Bước 5 — Định nghĩa quy trình incident response. Khi SEV-1: mở kênh sự cố (Slack channel riêng), chỉ định Incident Commander, phân vai Scribe và Comms, cập nhật status page. Có template sẵn để không phải nghĩ khi đang hoảng.
Bước 6 — Đo lường. Theo dõi MTTA (thời gian trung bình để acknowledge) và MTTR (mean time to recovery — thời gian trung bình để khôi phục). Đây là hai chỉ số phản ánh chất lượng on-call.
Bước 7 — Chạy postmortem sau mỗi sự cố lớn. Xây timeline, tìm nguyên nhân gốc, rút ra hành động cải thiện. (Văn hóa blameless và cách viết postmortem chi tiết là chủ đề của bài kế tiếp — ở đây chỉ cần biết postmortem là mắt xích khép vòng học hỏi.)
Bước 8 — Test định kỳ. Chạy diễn tập (game day / fire drill): cố tình gây một sự cố trên môi trường staging để kiểm tra escalation, runbook và phản xạ của đội có thật sự hoạt động không.
Lỗi thường gặp & mẹo
Lỗi: Không có Secondary. Chỉ cấu hình Primary rồi tin rằng người đó luôn phản hồi. Như ví dụ PayNhanh, chỉ cần một lần mất sóng là cả hệ thống sập kỷ luật. Luôn có ít nhất hai tầng.
Lỗi: Page mọi thứ. Alert fatigue giết chết on-call. Mẹo: trước khi tạo một alert dạng page, tự hỏi "nếu cái này kêu lúc 3 giờ sáng, có cần con người hành động ngay không?" Nếu không, cho nó vào dashboard chứ đừng page.
Lỗi: Không có mốc thời gian trong escalation. "Nếu Primary bận thì Secondary lo" là câu vô nghĩa. Phải là "sau 5 phút không acknowledge, tự động chuyển".
Lỗi: Người trực không có quyền hoặc không có runbook. Gọi người dậy nhưng họ không có quyền deploy, không có runbook, không biết bắt đầu từ đâu — chỉ tổ gây stress. Đảm bảo người trực có đủ quyền truy cập và tài liệu.
Mẹo: Bù đắp cho on-call. On-call là công việc thật, gây gián đoạn cuộc sống. Nhiều công ty trả phụ cấp on-call hoặc cho nghỉ bù. Điều này giữ tinh thần đội và giảm luân chuyển nhân sự.
Mẹo: Follow-the-sun cho đội đa vùng. Nếu công ty có văn phòng ở nhiều múi giờ (ví dụ VN và châu Âu), sắp lịch để mỗi vùng trực vào ban ngày của họ — không ai phải thức đêm thường xuyên.
Mẹo: Hand-off có bàn giao. Khi đổi ca, người trực cũ nên tóm tắt cho người mới: có sự cố nào đang treo, có gì cần theo dõi. Đừng chuyển ca trong im lặng.
Bài tập thực hành
- Thiết kế escalation policy. Cho một đội 5 kỹ sư, hãy viết ra escalation policy hoàn chỉnh với ba tầng (Primary, Secondary, Manager) kèm mốc thời gian cụ thể ở mỗi bước. Giải thích lý do chọn từng mốc.
- Phân loại severity. Với mỗi tình huống sau, gán SEV-1/2/3 và quyết định có page ngoài giờ hay không: (a) trang chủ tải chậm thêm 200ms; (b) toàn bộ chức năng đăng nhập lỗi; (c) một job báo cáo nội bộ chạy trễ 1 tiếng; (d) tỷ lệ lỗi API thanh toán tăng lên 30%.
- Viết một runbook. Chọn một sự cố giả định (ví dụ: "một pod trong Kubernetes liên tục CrashLoopBackOff") và viết runbook gồm: triệu chứng, các lệnh chẩn đoán, cách khắc phục tạm, khi nào escalate.
- Audit alert. Lấy 10 alert bất kỳ (thật hoặc tự nghĩ) và phân loại: cái nào nên page, cái nào chỉ nên vào dashboard. Với mỗi alert nên page, xác nhận nó có actionable không.
- Tính MTTA/MTTR. Cho một chuỗi 5 sự cố với thời điểm phát sinh, thời điểm acknowledge và thời điểm khôi phục, hãy tính MTTA và MTTR trung bình, rồi đề xuất một cải thiện.
Tóm tắt
On-call và incident response là nơi lý thuyết DevOps gặp áp lực thực chiến. Những điểm cốt lõi cần nhớ:
- Mô hình phân tầng Primary → Secondary → Manager với mốc thời gian rõ ràng ở mỗi bước là xương sống của on-call. Thiếu tầng nào, hệ thống gãy khi cần nhất.
- Severity quyết định cái gì được phép đánh thức con người. Chỉ page những gì thật sự khẩn cấp và cần hành động ngay.
- Incident Commander điều phối chứ không sửa lỗi; tách vai trò giữ cho SEV-1 không hỗn loạn.
- Runbook biến sự cố đáng sợ thành checklist làm theo được.
- Alert fatigue là kẻ thù thầm lặng — chất lượng alert quan trọng hơn số lượng.
- Con người là trung tâm: bảo vệ giấc ngủ, bù đắp công bằng và bàn giao ca tử tế giúp on-call bền vững.