6.4 KiB
FAIL — Failure Mode & Resilience Design —
| Version | 1.0 |
| Date | YYYY-MM-DD |
| Author | (skill sa-2-architecture) |
| Status | 🟡 Draft |
| Approved by | Tech Lead: — · SRE: — · QA: — |
| Source | SAD_… v1.0 · ICD_… v1.0 · QAS_… v1.0 |
| Scope | |
| Confidence | 🟡 |
Change Log
| Version | Date | Người sửa | Thay đổi | ADR |
|---|---|---|---|---|
| 1.0 | Bản đầu | — |
🔴 Đây là phần phân biệt SA giỏi và SA vẽ sơ đồ, và là phần bị bỏ nhiều nhất. Phần lớn sự cố production đến từ những ô còn trống trong tài liệu này.
1. Bảng phụ thuộc — mọi lời gọi vượt ranh giới process
HTTP, CSDL, cache, hàng đợi, file, hệ thống ngoài. Không sót cái nào.
| ID | Phụ thuộc | Từ CMP |
IF-nnn |
Timeout | Retry | Idempotent | Hết retry thì sao | Người dùng thấy gì | QAS |
|---|---|---|---|---|---|---|---|---|---|
FM-01 |
CSDL chính | CMP-01 |
— | … ms | 0 | — | trả lỗi 503 | "Hệ thống bận, thử lại sau" | QAS-002 |
FM-02 |
API POS ngoài | CMP-03 |
IF-005 |
… ms | 3 · backoff mũ + jitter | ✅ khoá: … | vào hàng đợi, xử lý sau | "Đã ghi nhận, đang xử lý" | QAS-007 |
🔴 Retry trên thao tác không idempotent là cách nhân đôi dữ liệu. Cột "Idempotent" phải được điền trước cột "Retry", không phải ngược lại.
2. Bốn câu hỏi cho mỗi phụ thuộc
Quy tắc D6. Không được bỏ câu nào — đặc biệt câu 1 và câu 4.
FM-01 — <tên phụ thuộc>
| # | Câu hỏi | Trả lời |
|---|---|---|
| 1 | Nó chậm thì sao? (nguy hiểm hơn hỏng: giữ tài nguyên, lan ngược lên tầng trên) | |
| 2 | Nó hỏng thì sao? (degrade được không, hay chết cả luồng) | |
| 3 | Nó trả sai dữ liệu thì sao? (có phát hiện được không, bằng gì) | |
| 4 | Nó hồi phục thì sao? (retry storm, thundering herd, cần backpressure không) |
🔴 Câu 1 là câu bị bỏ nhiều nhất. Một phụ thuộc hỏng hẳn thì mạch ngắt nhanh; một phụ thuộc trả lời sau 30 giây sẽ giữ hết connection pool và kéo sập cả hệ thống. Timeout luôn phải nhỏ hơn nhiều so với timeout của tầng gọi nó.
Ngân sách timeout theo tầng (timeout tầng ngoài phải > tổng timeout tầng trong)
| Tầng | Timeout | Ghi chú |
|---|---|---|
| Trình duyệt → gateway | … s | |
| Gateway → service | … s | |
| Service → CSDL | … ms | |
| Service → API ngoài | … ms | × số lần retry phải vẫn < timeout tầng trên |
FM-02 — <tên phụ thuộc>
(cùng cấu trúc)
3. Cơ chế chống lan lỗi
Ba cơ chế quyết định một lần cho toàn hệ thống, ghi thành ADR.
3.1 Circuit breaker
| Áp dụng cho | Ngưỡng mở | Thời gian nửa mở | Điều kiện đóng lại | Hành vi khi mở |
|---|---|---|---|---|
IF-005 |
… % lỗi trong … giây | … s | … lần thành công liên tiếp | trả fallback: … |
3.2 Backoff & jitter
| Quyết định | |
|---|---|
| Kiểu backoff | mũ / tuyến tính |
| Có jitter không | phải có — không jitter thì mọi client retry cùng lúc |
| Số lần tối đa | |
| Tổng thời gian tối đa |
3.3 Bulkhead (tách pool tài nguyên)
| Nhóm | Pool riêng cho | Kích thước | Vì sao tách |
|---|---|---|---|
| (ví dụ: gọi API ngoài dùng pool riêng, để nó cạn không ảnh hưởng luồng nội bộ) |
4. Suy giảm có kiểm soát (graceful degradation)
Khi một phần hỏng, hệ thống làm được gì thay vì chết hẳn.
| Thành phần hỏng | Chức năng mất | Chức năng vẫn chạy | Người dùng thấy gì | Ai quyết mức degrade |
|---|---|---|---|---|
| Cache | ||||
| API gợi ý | ||||
| Hệ thống báo cáo |
🔴 Mức degrade là quyết định nghiệp vụ, không phải kỹ thuật. PO phải chốt: thà hiển thị dữ liệu cũ 10 phút hay thà báo lỗi? Hai lựa chọn khác nhau ở rủi ro nghiệp vụ, không ở kỹ thuật.
5. Kịch bản hỏng toàn hệ thống
| # | Kịch bản | Phát hiện bằng | Sau bao lâu phát hiện | Hệ quả | Cách xử lý | Runbook |
|---|---|---|---|---|---|---|
| 1 | Mất kết nối CSDL chính | … phút | ||||
| 2 | Hàng đợi đầy | |||||
| 3 | Rò rỉ bộ nhớ, service khởi động lại liên tục | |||||
| 4 | Hệ thống ngoài trả 200 nhưng dữ liệu sai | |||||
| 5 | Tăng tải đột biến ×10 | |||||
| 6 | Deploy sai, phải rollback | INF §7 |
6. Dữ liệu trong lúc lỗi
| Câu hỏi | Trả lời |
|---|---|
| Giao dịch đang dở khi service chết ⇒ trạng thái nào còn lại | |
| Ai dọn trạng thái nửa vời, sau bao lâu | |
| Message đã nhận nhưng chưa xử lý xong ⇒ mất hay xử lý lại | |
| Poison message (xử lý mãi không được) ⇒ đi đâu | DLQ · giữ … · ai xử lý |
| Có mất dữ liệu nào chấp nhận được không | (khớp RPO ở INF §5) |
7. Diễn tập
Failure mode chưa diễn tập là giả thuyết. AG3 yêu cầu ít nhất các FM mức cao đã được thử.
FM |
Cách diễn tập | Môi trường | Lần gần nhất | Kết quả | Đúng như thiết kế? |
|---|---|---|---|---|---|
FM-01 |
tắt CSDL replica | stg | ☐ | ||
FM-02 |
chặn mạng tới API ngoài | stg | ☐ |
🔴 Diễn tập hay phát hiện: timeout cấu hình khác tài liệu, retry không có jitter, cảnh báo không bắn, runbook viết cho hệ thống phiên bản cũ. Đó chính là giá trị của việc diễn tập.
8. Giả định & Ngoài phạm vi
Giả định:
| ID | Giả định | Cách xác minh | Nếu sai |
|---|---|---|---|
ASM-nn |
API ngoài giữ đúng SLA đã cam kết | theo dõi thực tế |
Ngoài phạm vi:
- (ví dụ: không xử lý trường hợp mất toàn bộ vùng cloud — thuộc DR ở
INF§5)
9. Open Questions
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | Hệ quả nếu trả lời ngược |
|---|