Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 8 — Vận hành thực tế: observability, kẹt đơn và tình huống production

Đã đọc 0/8 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Code chạy được trong demo là một chuyện; giữ cho hàng nghìn quy trình xuyên hệ thống lành mạnh trong production là chuyện khác. Bài cuối tập trung vào vận hành: nhìn thấy quy trình đang ở đâu, phát hiện đơn kẹt, và xử lý các tình huống thật sẽ xảy ra.

Correlation ID: sợi chỉ xuyên hệ thống

Mỗi quy trình sinh một correlation ID (thường là order_id hoặc một trace-id) và gắn nó vào mọi lời gọi tới mọi hệ thống, vào mọi dòng log. Khi có sự cố, bạn grep một ID và thấy toàn bộ hành trình qua WMS, accounting, payment.

[2026-07-10 10:22:01] order=ORD-8841 step=reserve   status=ok    wms_id=R-77
[2026-07-10 10:22:03] order=ORD-8841 step=invoice   status=ok    inv=INV-52
[2026-07-10 10:22:19] order=ORD-8841 step=charge    status=503   attempt=1
[2026-07-10 10:22:22] order=ORD-8841 step=charge    status=ok    pay=PAY-19

Ba tín hiệu phải theo dõi

  • Đơn kẹt (stuck): state không phải trạng thái cuối và updated_at cũ hơn ngưỡng (ví dụ 15 phút). Đây là chỉ báo sức khỏe quan trọng nhất.
  • Tỷ lệ vào FAILED/COMPENSATED: tăng đột biến nghĩa là một hệ thống ngoài đang hỏng.
  • Độ trễ mỗi bước và số retry trung bình: phát hiện đối tác chậm dần trước khi thành sự cố.
-- Bảng điều khiển "đơn kẹt"
SELECT order_id, state, attempt_count, updated_at
FROM order_workflow
WHERE state NOT IN ('PAID','COMPENSATED','FAILED')
  AND updated_at < now() - interval '15 minutes'
ORDER BY updated_at;

Runbook: các tình huống thật

Tình huống A — Payment gateway sập 30 phút. Retry+backoff giữ đơn ở INVOICED và thử lại; circuit breaker giảm tải. Khi gateway hồi phục, các đơn tự tiếp tục. Việc của bạn: theo dõi hàng đợi, không hoảng hủy hàng loạt.

Tình huống B — Một đơn kẹt ở RESERVED 2 giờ. Kiểm log: bước invoice ném lỗi permanent 422 ("khách bị khóa công nợ"). Đây là quyết định nghiệp vụ: kích hoạt bù trừ (nhả hàng) và báo sales, không retry.

Tình huống C — Nghi ngờ double-charge. Tra correlation ID; nếu idempotency key được tôn trọng, gateway trả cùng payment_id → không trùng. Nếu thấy hai payment_id khác nhau cho một đơn, đó là bug key — vá và refund khoản thừa.

Tình huống D — Deploy phiên bản mới giữa lúc nhiều đơn đang chạy. Vì state bền và mỗi bước idempotent, worker mới đọc state cũ và tiếp tục an toàn — miễn là bạn không đổi ý nghĩa trạng thái cũ. Đổi schema state thì phải migrate tương thích ngược.

Khung tư duy vận hành: mỗi đơn luôn đang tiến hoặc đang được chú ý

Một orchestration khỏe mạnh có tính chất: không đơn nào im lặng thất bại. Mỗi đơn hoặc đang tiến tới trạng thái cuối, hoặc đã ở trạng thái cuối, hoặc đang nằm trong hàng chờ người xử lý có cảnh báo. Không có "vùng xám" mà đơn biến mất không ai biết.

Checklist sẵn sàng production

  • [ ] Correlation ID trên mọi log và mọi lời gọi ngoài.
  • [ ] Dashboard/truy vấn liệt kê đơn kẹt theo updated_at.
  • [ ] Cảnh báo khi tỷ lệ FAILED vượt ngưỡng.
  • [ ] Runbook cho: gateway sập, đơn kẹt, nghi double-charge.
  • [ ] Công cụ cho ops: xem state, retry thủ công, ép bù trừ.
  • [ ] Migration state tương thích ngược khi deploy.
  • [ ] Test hồi phục: giết worker giữa chừng, xác nhận đơn chạy tiếp.

Các bước thiết lập vận hành

  • Chuẩn hóa log có order_id và truyền ID xuống mọi adapter.
  • Dựng truy vấn/dashboard "đơn kẹt" chạy mỗi vài phút.
  • Đặt alert theo tỷ lệ FAILED và tuổi đơn kẹt.
  • Viết runbook ngắn cho 3–4 tình huống hàng đầu.
  • Cung cấp nút ops: retry, ép compensate, đọc state — có ghi log ai thao tác.

Sai lầm thường gặp

  • Không có correlation ID: sự cố xảy ra, bạn không lần được đơn qua các hệ thống.
  • Không giám sát đơn kẹt: đơn treo âm thầm, khách phàn nàn mới biết.
  • Ops chỉ có DB thô để sửa tay: dễ chuyển state sai, phá vỡ bất biến của state machine.
  • Deploy đổi ý nghĩa trạng thái cũ: các đơn đang chạy diễn giải sai state, hỏng hàng loạt.
  • Phản ứng thái quá khi đối tác sập: hủy hàng loạt thay vì để retry/backoff làm việc, gây thiệt hại không cần thiết.
Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi