Mở đầu — vì sao bài này quan trọng
Khi bạn còn là developer, bạn vẽ kiến trúc hệ thống theo bản năng: một sơ đồ với đủ thứ box và mũi tên, vài cái database, mấy con service, một đống Redis cache và message queue chen chúc nhau. Bạn hiểu nó vì bạn viết ra nó. Nhưng giờ bạn ngồi vào ghế BA, và sơ đồ "đúng kỹ thuật" đó lại khiến giám đốc kinh doanh, khách hàng, hay một bạn QA mới vào nghề… lắc đầu không hiểu gì.
Đây chính là cái bẫy đầu tiên của dev-turned-BA khi nói về kiến trúc: bạn vẽ cho người giống bạn, chứ không vẽ cho người cần đọc. Một BA giỏi không phải người vẽ sơ đồ phức tạp nhất, mà là người chọn đúng mức độ chi tiết cho đúng đối tượng người nghe.
Bài này tập trung vào một công cụ duy nhất nhưng cực kỳ quyền lực: C4 Model của Simon Brown — một cách tiếp cận "zoom in / zoom out" để mô tả kiến trúc phần mềm thành 4 cấp độ, từ tổng quan business cho tới chi tiết kỹ thuật. Với nền tảng developer sẵn có, bạn có lợi thế khổng lồ: bạn đã hiểu hệ thống bên trong vận hành thế nào. Việc của bài này là dạy bạn cách kể lại sự hiểu biết đó một cách có cấu trúc, để cả người business lẫn người kỹ thuật đều gật gù. Và khi chạm tới microservice — kiến trúc đang thống trị các dự án lớn ở Việt Nam — bạn sẽ biết cách mô tả nó mà không sa lầy vào hàng trăm service.
Khái niệm cốt lõi
Vấn đề "bản đồ một tỉ lệ"
Hãy tưởng tượng Google Maps chỉ có duy nhất một mức zoom. Nếu chỉ có mức "toàn thế giới", bạn không tìm được quán cà phê. Nếu chỉ có mức "từng con hẻm", bạn không biết Việt Nam nằm ở đâu trên bản đồ. Sơ đồ kiến trúc cũng vậy: một sơ đồ duy nhất nhồi nhét mọi thứ thì vô dụng cho mọi đối tượng.
C4 Model giải quyết điều này bằng cách định nghĩa 4 cấp độ zoom, mỗi cấp là một bản đồ ở một tỉ lệ khác nhau:
Cấp 1 — System Context (Bối cảnh hệ thống)
Đây là bức tranh cao nhất, "nhìn từ vệ tinh". Nó trả lời câu hỏi: Hệ thống của chúng ta là gì, ai dùng nó, và nó nói chuyện với những hệ thống bên ngoài nào?
Trên sơ đồ này chỉ có ba loại thứ:
- Hệ thống của bạn (một hộp duy nhất ở giữa — không phơi bày ruột gan bên trong).
- Người dùng / actor (khách hàng, nhân viên, admin…).
- Hệ thống bên ngoài (cổng thanh toán VNPAY, dịch vụ gửi SMS, hệ thống core banking, Google OAuth…).
Cấp 2 — Container (Vùng chứa)
Lưu ý quan trọng: "Container" trong C4 không phải Docker container. Ở đây "container" nghĩa là một thứ có thể chạy hoặc lưu trữ độc lập — một ứng dụng web, một mobile app, một backend API, một database, một message broker, một single-page application.
Sơ đồ Container "phóng to" cái hộp hệ thống ở Cấp 1 ra, cho thấy nó được tạo thành từ những khối triển khai nào và chúng giao tiếp với nhau bằng giao thức gì (HTTPS/JSON, gRPC, JDBC…).
Đây là sơ đồ bạn đưa cho tech lead, kiến trúc sư, DevOps, và cả BA khác. Nó là cầu nối vàng giữa business và kỹ thuật.
Cấp 3 — Component (Thành phần)
Phóng to một container (ví dụ: backend API) để thấy nó gồm các nhóm chức năng/module nào bên trong: Controller, Service, Repository, các module nghiệp vụ như "Order Management", "Payment Processing"… Cấp này dành cho developer trong team đó.
Cấp 4 — Code
Mức chi tiết nhất: class diagram, sequence diagram cho một component cụ thể. Thực tế, cấp này hiếm khi cần vẽ tay — IDE tự sinh ra được, và nó lỗi thời rất nhanh. Phần lớn công việc của BA dừng ở Cấp 1 và Cấp 2.
Quy tắc vàng cho BA
Hãy ghi nhớ: càng lên cấp cao, người đọc càng "business"; càng xuống cấp thấp, người đọc càng "technical". Với vai trò BA, 80% giá trị bạn tạo ra nằm ở Cấp 1 (System Context) và Cấp 2 (Container). Đừng cố vẽ Cấp 3, Cấp 4 — đó là việc của dev, và nếu bạn ôm hết thì bạn đang quay lại làm dev chứ không phải BA.
C4 và microservice
Microservice là nơi C4 phát huy sức mạnh nhất — và cũng là nơi nhiều BA bị "ngợp". Một hệ thống microservice thật có thể có 40–80 service. Nếu bạn vẽ tất cả lên một sơ đồ, kết quả là cái mà cộng đồng gọi đùa là "death star diagram" — chi chít mũi tên như một ngôi sao tử thần, không ai đọc nổi.
Cách C4 xử lý: ở Cấp 1, toàn bộ 80 service vẫn chỉ là một hộp duy nhất — "Hệ thống E-commerce". Ở Cấp 2, bạn mới tách ra các container quan trọng theo domain nghiệp vụ (Order Service, Payment Service, Inventory Service…) — và bạn được phép vẽ nhiều sơ đồ Cấp 2 nhỏ, mỗi sơ đồ tập trung vào một luồng nghiệp vụ, thay vì một sơ đồ khổng lồ. Đây là kỹ năng "kể chuyện theo luồng" mà BA cần làm chủ.
Tình huống thực tế
Ví dụ 1 — Tiki và cuộc họp với nhà đầu tư
Giả định bối cảnh: một sàn TMĐT lớn tại Việt Nam (tạm gọi theo mô hình Tiki) chuẩn bị họp với một nhà đầu tư Nhật để gọi vốn vòng Series C. Anh BA — vốn xuất thân backend developer — được giao chuẩn bị slide kiến trúc hệ thống.
Theo bản năng cũ, anh vẽ một sơ đồ với 52 microservice, 3 cụm Kafka, 5 PostgreSQL, Elasticsearch, Redis cluster, và một mê cung API gateway. Trong buổi review nội bộ, chị Giám đốc Sản phẩm hỏi đúng một câu: "Nhà đầu tư cần biết hệ thống của ta kết nối với ai và xử lý được bao nhiêu đơn, chứ không cần biết ta có bao nhiêu con Kafka."
Anh BA quay lại, áp dụng C4 Cấp 1. Sơ đồ mới chỉ còn: hộp "Nền tảng TMĐT Tiki" ở giữa; các actor "Người mua", "Nhà bán hàng", "Nhân viên kho"; và các hệ thống bên ngoài "VNPAY (thanh toán)", "GHN/GHTK (vận chuyển)", "Tổng cục Thuế (hóa đơn điện tử)", "Zalo/SMS (thông báo)". Kèm theo vài con số: "xử lý 4 triệu đơn/tháng, tích hợp 6 đối tác logistics".
Bài học: Cùng một hệ thống, nhưng đối tượng người nghe quyết định cấp độ zoom. Nhà đầu tư cần System Context, không cần Container. Anh BA chọn sai cấp ban đầu vì tư duy dev còn ngấm sâu.
Ví dụ 2 — Ngân hàng số và bài toán tích hợp Core Banking
Bối cảnh: một ngân hàng tầm trung tại TP.HCM xây dựng app mobile banking mới, tích hợp với hệ thống Core Banking đời cũ (T24). Đội dự án có 4 squad, mỗi squad làm vài service. BA cần một tài liệu kiến trúc để tech lead các squad, đội bảo mật, và đối tác tư vấn nước ngoài cùng đọc.
BA quyết định vẽ một sơ đồ Cấp 2 (Container). Trên đó có: "Mobile App (iOS/Android)", "API Gateway", "Auth Service", "Account Service", "Transfer Service", "Notification Service", và quan trọng nhất — một adapter container tên "Core Banking Adapter" nối tới hộp hệ thống bên ngoài "T24 Core Banking" qua giao thức "ISO 8583 / SOAP". BA ghi rõ mũi tên: "Transfer Service → Core Banking Adapter (gRPC) → T24 (SOAP/XML)".
Chính nhờ sơ đồ này, đội bảo mật phát hiện ngay: lệnh chuyển tiền đi qua adapter dùng SOAP/XML cũ kỹ, cần thêm lớp mã hóa và audit log. Một rủi ro được lôi ra ánh sáng trước khi code, chỉ nhờ một sơ đồ Container đặt đúng tầm.
Bài học: Cấp 2 (Container) là nơi BA tạo ra giá trị lớn nhất — nó đủ chi tiết để lộ ra điểm tích hợp và rủi ro, nhưng đủ trừu tượng để mọi stakeholder cùng đọc. Việc tách riêng "Core Banking Adapter" thành một container giúp cả team thấy rõ ranh giới giữa hệ thống mới và hệ thống legacy.
Ví dụ 3 — Startup edtech và "death star diagram"
Bối cảnh: một startup edtech ở Hà Nội (giả định, ~30 người) chuyển từ monolith sang microservice sau khi gọi vốn. Bạn BA mới chuyển từ dev được giao "vẽ lại toàn bộ kiến trúc cho tài liệu onboarding nhân viên mới".
Bạn hào hứng vẽ tất cả 28 service lên một canvas Figma duy nhất. Kết quả: mũi tên đan chéo nhau, người mới vào nhìn 5 phút rồi… bỏ cuộc. CTO góp ý: "Đừng vẽ bản đồ toàn bộ thành phố trong một tờ. Hãy vẽ từng tuyến đường."
Bạn áp dụng tư duy C4 "nhiều sơ đồ Cấp 2 theo luồng". Thay vì một sơ đồ, bạn tạo ba sơ đồ nhỏ: (1) Luồng "Học viên đăng ký khóa học" — chỉ hiện 5 service liên quan; (2) Luồng "Giảng viên upload bài giảng" — hiện 4 service; (3) Luồng "Thanh toán & xuất hóa đơn" — hiện 4 service. Mỗi sơ đồ kể một câu chuyện trọn vẹn. Nhân viên mới đọc một mạch là hiểu.
Bài học: Với microservice, đừng vẽ "tất cả mọi thứ một lúc". Hãy cắt theo use case / luồng nghiệp vụ và vẽ nhiều sơ đồ Cấp 2 có trọng tâm. Đây là kỹ năng tư duy nghiệp vụ — chính là thứ phân biệt BA với một người vẽ sơ đồ kỹ thuật thuần túy.
Hướng dẫn từng bước
Đây là quy trình thực dụng để bạn tạo tài liệu kiến trúc theo C4 cho một dự án:
Bước 1 — Xác định người đọc trước, vẽ sau. Hỏi rõ: tài liệu này cho ai? Nếu cho sponsor/khách hàng → dừng ở Cấp 1. Nếu cho team kỹ thuật & DevOps → cần tới Cấp 2. Nếu cho dev trong một service → mới cần Cấp 3. Đừng bao giờ vẽ trước khi biết người đọc.
Bước 2 — Vẽ System Context (Cấp 1) trước tiên, luôn luôn. Đặt hệ thống của bạn vào giữa như một hộp đen. Liệt kê mọi người dùng (vai trò, không phải cá nhân) xung quanh. Liệt kê mọi hệ thống bên ngoài mà bạn tích hợp. Vẽ mũi tên có nhãn động từ rõ ràng: "Người mua → [Đặt hàng, thanh toán] → Hệ thống", "Hệ thống → [Gửi yêu cầu thanh toán] → VNPAY".
Bước 3 — Phóng to thành Container (Cấp 2). Mở hộp đen ra. Liệt kê các khối triển khai độc lập: web app, mobile app, các backend service, database, message queue, cache. Với microservice, nhóm theo domain nghiệp vụ, đừng liệt kê kiểu hạ tầng. Ghi rõ công nghệ và giao thức trên mỗi mũi tên (ví dụ "HTTPS/JSON", "gRPC", "Kafka topic: order-created").
Bước 4 — Cắt theo luồng nếu hệ thống quá lớn. Nếu có hơn ~10 container, đừng nhồi vào một sơ đồ. Tạo nhiều sơ đồ Cấp 2, mỗi cái cho một luồng nghiệp vụ chính (đăng ký, thanh toán, giao hàng…). Mỗi sơ đồ chỉ hiện các container tham gia luồng đó.
Bước 5 — Chỉ vẽ Cấp 3/Cấp 4 khi thực sự cần. Đa số trường hợp BA dừng ở Cấp 2. Chỉ xuống Cấp 3 khi cần làm rõ một logic phức tạp cho dev. Cấp 4 hầu như để IDE tự sinh.
Bước 6 — Chú thích đầy đủ và phiên bản hóa. Mỗi sơ đồ phải có: tiêu đề, ngày cập nhật, người chịu trách nhiệm, và một legend (chú giải ký hiệu). Sơ đồ không có legend là sơ đồ chỉ người vẽ hiểu. Lưu trên Confluence/Notion kèm phiên bản, vì kiến trúc thay đổi liên tục.
Công cụ gợi ý: draw.io (miễn phí, dễ), Excalidraw (nhanh, nhìn thân thiện), hoặc Structurizr / PlantUML với cú pháp C4-PlantUML nếu bạn thích "diagram-as-code" — với nền dev, bạn sẽ thấy viết sơ đồ bằng code rất hợp gu và dễ version control bằng Git.
Lỗi thường gặp & mẹo
Lỗi 1 — Trộn lẫn các cấp độ trên cùng một sơ đồ. Bạn vẽ System Context nhưng lại nhét một con Redis cache vào. Sai. Redis là chi tiết Cấp 2. Mỗi sơ đồ phải nhất quán một cấp zoom. Mẹo: trước khi thêm bất kỳ box nào, tự hỏi "thứ này thuộc tỉ lệ bản đồ nào?".
Lỗi 2 — Nhầm "Container" của C4 với Docker container. Rất nhiều dev-turned-BA dính lỗi này. Container trong C4 là đơn vị triển khai/lưu trữ logic (một app, một DB), không phải Docker. Một service có thể chạy trên nhiều Docker container nhưng vẫn là một C4 container.
Lỗi 3 — Mũi tên không có nhãn. Mũi tên trống nghĩa là "có liên quan gì đó". Vô dụng. Mỗi mũi tên phải nói rõ: làm gì (động từ) và bằng gì (giao thức). "Service A → Service B" là sai; "Service A → [Lấy thông tin tồn kho, gRPC] → Service B" mới đúng.
Lỗi 4 — Vẽ quá chi tiết vì còn tư duy dev. Bạn muốn show off việc bạn hiểu cả connection pool, retry policy, circuit breaker. Đừng. Với vai trò BA, chi tiết đó làm loãng thông điệp. Hãy hỏi: "Người đọc cần thông tin này để ra quyết định gì?" Nếu không có quyết định nào, bỏ đi.
Lỗi 5 — Vẽ một lần rồi để mốc meo. Sơ đồ kiến trúc lỗi thời còn nguy hiểm hơn không có sơ đồ, vì nó dẫn người ta đi sai. Mẹo: gắn việc cập nhật sơ đồ vào Definition of Done của các epic lớn, hoặc dùng diagram-as-code để review cùng pull request.
Mẹo lớn nhất: Tận dụng lợi thế dev của bạn để hiểu sâu, nhưng dùng kỷ luật BA để trình bày nông phù hợp người nghe. Sức mạnh của bạn không phải vẽ được sơ đồ phức tạp nhất, mà là biết khi nào không vẽ chi tiết.
Bài tập thực hành
Chọn một hệ thống bạn từng làm hoặc đang hiểu rõ (ví dụ một app đặt đồ ăn, một sàn TMĐT nội bộ, hệ thống quản lý khóa học…). Thực hiện:
- Vẽ sơ đồ System Context (Cấp 1). Tối đa 1 hộp hệ thống ở giữa, liệt kê tất cả actor và hệ thống bên ngoài. Mỗi mũi tên phải có nhãn động từ. Tự kiểm: một người không biết kỹ thuật có hiểu được không?
- Vẽ sơ đồ Container (Cấp 2). Phóng to hộp hệ thống thành các container (web, mobile, các service, DB, queue). Ghi công nghệ + giao thức trên mỗi mũi tên. Nếu có hơn 10 container, hãy cắt thành 2–3 sơ đồ theo luồng nghiệp vụ.
- Viết một đoạn 5–7 câu giải thích: nếu sếp business chỉ được xem một sơ đồ, bạn đưa cấp nào và vì sao? Nếu tech lead mới vào team cần onboard, bạn đưa cấp nào?
- Tự soi lỗi: rà lại hai sơ đồ và đánh dấu xem bạn có mắc lỗi nào trong mục "Lỗi thường gặp" không (trộn cấp độ, mũi tên không nhãn, quá chi tiết…).
Tóm tắt
- C4 Model là "Google Maps cho kiến trúc": 4 mức zoom — System Context, Container, Component, Code — mỗi mức cho một đối tượng người đọc khác nhau.
- Cấp 1 (System Context) dành cho sponsor/khách hàng: hệ thống là một hộp đen, xung quanh là người dùng và hệ thống bên ngoài.
- Cấp 2 (Container) là nơi BA tạo giá trị lớn nhất: lộ ra các khối triển khai, điểm tích hợp và rủi ro, nhưng vẫn đủ dễ đọc cho cả business lẫn kỹ thuật.
- Cấp 3 & 4 chủ yếu là việc của dev; BA hiếm khi cần xuống tới đây.
- "Container" của C4 không phải Docker container — đó là đơn vị triển khai/lưu trữ logic.
- Với microservice, đừng vẽ "death star" gồm tất cả service; hãy giữ chúng là một hộp ở Cấp 1, rồi cắt thành nhiều sơ đồ Cấp 2 theo luồng nghiệp vụ.
- Lợi thế dev của bạn là hiểu sâu hệ thống; kỷ luật BA là chọn đúng cấp zoom cho đúng người. Luôn xác định người đọc trước khi vẽ.