Bỏ qua để đến nội dung
Knowledge Hub

Ngoài ADR: design doc, Diátaxis, runbook và sơ đồ C4 Trung cấp

Thời gian đọc ước tính: 6 phút

Trang này trả lời: ngoài ADR, team cần những tài liệu nào, mỗi loại viết cho ai, và trông thế nào khi viết đúng.

Design doc là tài liệu tương đối không chính thức, viết trước khi code, để nêu chiến lược và trade-off rồi xin review. Nhiều công ty gọi nó là RFC.

Malte Ubl mô tả cấu trúc hay dùng ở Google:

  • Context and scope
  • Goals and non-goals
  • The actual design
  • Alternatives considered
  • Cross-cutting concerns (security, privacy, observability)
Design doc / RFC ADR
Thời điểm Trước khi làm, khi còn mơ hồ Lúc chốt quyết định (thường cuối design review)
Mục đích Khám phá phương án, xin phản biện, tạo đồng thuận Ghi lại một quyết định và lý do
Phạm vi Cả một thay đổi, có thể sinh nhiều quyết định Đúng một quyết định
Độ dài Ubl: khoảng 10–20 trang cho dự án lớn, “mini design doc” 1–3 trang 1–2 trang (Nygard)
Sau khi xong Lỗi thời dần; Ubl khuyên cập nhật khi thiết kế đổi lúc còn đang làm Bất biến; đổi ý thì supersede
Người đọc chính Reviewer hiện tại Kỹ sư tương lai

Đang tải diagram…

Design doc có thể cũ đi; ADR thì không cần cập nhật.

Ubl cũng nói khi nào không viết design doc: bài toán không mơ hồ, hoặc doc thực chất là “implementation manual” không có trade-off. Khi đó viết thẳng ADR, hoặc chỉ cần PR description tốt.

Diátaxis: tổ chức phần tài liệu còn lại

Phần tiêu đề “Diátaxis: tổ chức phần tài liệu còn lại”

Phần còn lại hay hỏng vì trộn lẫn: README vừa là tutorial, vừa là reference, vừa giải thích kiến trúc. Diátaxis chia tài liệu theo nhu cầu người đọc thành bốn loại:

Loại Diátaxis mô tả Ví dụ cho order service Dấu hiệu viết sai
Tutorial Một bài học; người đọc học bằng cách làm README quickstart: clone, docker compose up, tạo đơn đầu tiên, thấy event trong Kafka Rẽ nhánh “nếu bạn dùng X thì…”; giải thích dài
How-to guide Hướng dẫn đạt một mục tiêu thực tế, cho người đã biết việc “Replay event outbox cho một khoảng thời gian”, “Rotate secret Kafka”, runbook Dạy lại khái niệm từ đầu
Reference Mô tả kỹ thuật chính xác, đầy đủ, trung tính OpenAPI spec, JSON schema event, bảng env var kèm default Có ý kiến, có “nên”; viết tay rồi lệch code
Explanation Bối cảnh, lý do, bức tranh lớn ADR, architecture.md với sơ đồ C4, “Vì sao đơn có 7 trạng thái” Chèn lệnh từng bước

Hai mẹo thực dụng:

  • Reference nên sinh từ code (OpenAPI từ decorator NestJS, bảng env var từ schema validate config). Thứ viết tay sẽ lệch.
  • README là cửa vào, không phải kho. Giữ quickstart ngắn, link sang how-to, reference và docs/adr/.

Runbook là how-to guide cho người bị page lúc 3 giờ sáng, có thể không phải người viết code. Mỗi alert nên link tới đúng một runbook; alert không có runbook là alert chưa xong.

Prometheus mô tả annotations là chỗ chứa thông tin dài hơn như mô tả alert hoặc link runbook:

- alert: OutboxBacklogHigh
# metric do relay tự export: tuổi (giây) của dòng pending cũ nhất
expr: outbox_oldest_pending_age_seconds > 60
for: 5m
labels:
severity: page
annotations:
summary: Outbox có dòng pending cũ hơn 60s
runbook_url: https://git.example.com/order-service/-/blob/main/docs/runbooks/outbox-backlog.md

Runbook tương ứng:

# Runbook: OutboxBacklogHigh
Alert: dòng outbox pending cũ nhất > 60s trong 5 phút. Dashboard: <link>
Owner: team Checkout. Cập nhật lần cuối: 2026-09-12 (bởi Minh)
## Ảnh hưởng
Shipping nhận OrderPaid chậm. Thanh toán KHÔNG bị ảnh hưởng (xem ADR-0012).
## Chẩn đoán (theo thứ tự)
1. Relay có chạy không? `kubectl get pods -l app=outbox-relay`
2. Kafka có nhận không? Xem lỗi publish trên dashboard relay.
3. Có dòng "độc" retry mãi không?
SELECT id, event_type, created_at FROM outbox
WHERE published_at IS NULL ORDER BY id LIMIT 20;
## Xử lý
- Relay crash loop: rollback relay về image trước.
- Kafka down: không làm gì với outbox; backlog sẽ tự xả khi Kafka về. Báo #inc-kafka.
- Dòng độc: KHÔNG xoá. Chuyển sang bảng outbox_parked theo hướng dẫn <link>, mở ticket.
## Escalation
Sau 30 phút chưa giảm: gọi secondary on-call Checkout, rồi SRE.

Những điểm làm runbook dùng được:

  • Ảnh hưởng tới người dùng nói trước.
  • Lệnh copy-paste được, theo thứ tự chẩn đoán.
  • Ghi rõ việc không được làm.
  • Có ngày cập nhật và owner.

Ngưỡng alert nên xuất phát từ SLO (xem SLI, SLO và error budget).

C4 model của Simon Brown có bốn mức: System context, Container, Component, Code. Trang C4 nói thẳng: system context và container diagram đủ cho đa số team; chỉ vẽ mức nào thêm giá trị.

“Container” trong C4 là ranh giới runtime chạy code hoặc lưu dữ liệu, không phải Docker container.

Đang tải diagram…

Cách đọc:

Mức Cách nhìn sơ đồ trên Trả lời
1 — System context Coi khung Order system là một hộp Ai dùng, nói chuyện với hệ thống nào
2 — Container Mở khung ra Process và datastore nào, giao tiếp bằng gì
3 — Component Bên trong Order API Thường không đáng vẽ tay: đổi theo từng refactor

Quy tắc giữ sơ đồ đúng:

  • Sơ đồ là code: Mermaid trong docs/architecture.md.
  • Mỗi mũi tên ghi giao thức hoặc ý nghĩa.
  • PR thêm datastore hay tích hợp mới phải sửa sơ đồ.

Tiếp theo: Giữ tài liệu sống và checklist.