init git
This commit is contained in:
153
.claude/skills/sa-2-architecture/templates/failure-mode.md
Normal file
153
.claude/skills/sa-2-architecture/templates/failure-mode.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# FAIL — Failure Mode & Resilience Design — <PROJECT>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Version** | 1.0 |
|
||||
| **Date** | YYYY-MM-DD |
|
||||
| **Author** | <SA> (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 |
|
||||
|---|---|---|---|---|---|
|
||||
Reference in New Issue
Block a user