WEBSITE ĐANG PHÁT TRIỂN

5 câu hỏi tôi luôn hỏi trước khi bắt đầu thiết kế hệ thống mới

Không phải mọi hệ thống đều cần microservices. Không phải mọi hệ thống cần scale tới triệu users. Vấn đề là phần lớn developer bắt tay vào thiết kế mà không hỏi đúng câu hỏi trước - và hệ quả thì đau hơn mọi người nghĩ.

Cái dự án tôi muốn quên

Năm 2019, tôi nhận một dự án platform nội bộ cho một tập đoàn bán lẻ lớn. Requirement nghe có vẻ đơn giản: "Hệ thống quản lý inventory tập trung, kết nối 50 cửa hàng."

Team tôi hào hứng. Chúng tôi họp 2 ngày để thiết kế kiến trúc - microservices, event sourcing, CQRS, Kubernetes, API gateway. Đẹp như mơ trên whiteboard.

6 tháng sau, chúng tôi deliver được 30% feature. Chi phí vượt 2x budget. Và cái hệ thống "đơn giản" đó có độ phức tạp vận hành cao đến mức team IT của khách hàng không thể tự maintain.

Nhìn lại, vấn đề không phải là team kém. Vấn đề là ngay từ đầu, chúng tôi đã không hỏi đúng câu hỏi.


Câu hỏi 1: "Scale lên bao nhiêu là đủ - và trong bao lâu?"

Đây là câu hỏi tôi hỏi đầu tiên, mọi lần, không ngoại lệ.

Khách hàng thường nói "cần scale được". Nhưng scale được nghĩa là gì? 100 users? 10,000? 1 triệu? Trong 6 tháng? 5 năm?

Con số này ảnh hưởng trực tiếp đến mọi quyết định kiến trúc: database nào, caching strategy nào, có cần queue không, có cần horizontal scale không.

Dự án inventory của tôi có 50 cửa hàng, mỗi cửa hàng 2-3 nhân viên dùng. Tối đa là 150 concurrent users. Tôi đã thiết kế hệ thống như thể cần phục vụ 50,000 concurrent users. Overkill hoàn toàn.

Công thức tôi dùng bây giờ:

Peak concurrent users × 3 (safety buffer) = capacity target

Nếu target đó một monolith .NET API + single SQL Server xử lý được - thì dùng monolith. Đơn giản luôn tốt hơn.


Câu hỏi 2: "Ai sẽ maintain hệ thống này sau khi tôi bàn giao?"

Câu hỏi này nghe có vẻ không liên quan đến kỹ thuật. Nhưng nó ảnh hưởng rất lớn đến technology choice.

Tôi từng thiết kế một hệ thống beautiful với Event-driven architecture, Kafka, separate microservices cho mỗi domain. Technically flawless. Rồi bàn giao cho team IT của khách hàng - 3 người, background chủ yếu là sysadmin, không có ai từng dùng Kafka.

6 tháng sau họ gọi lại: "Anh ơi hệ thống lag, không biết tại sao." Tôi debug 2 ngày mới tìm ra consumer group offset bị lệch - một vấn đề hoàn toàn bình thường với Kafka nhưng cần người biết Kafka để xử lý.

Câu hỏi tôi hỏi bây giờ: "Team bạn có bao nhiêu người? Background là gì? Họ đã từng dùng [technology X] chưa?"

Nếu câu trả lời là "không" - thì technology X dù tốt đến đâu cũng không phải lựa chọn đúng.


Câu hỏi 3: "Thứ gì KHÔNG THỂ sai - và thứ gì có thể down tạm thời?"

Không phải mọi thứ trong hệ thống đều quan trọng như nhau. Nhưng developer thường thiết kế như thể mọi thứ đều critical.

Trong e-commerce, tôi luôn hỏi: "Nếu tôi phải chọn, cái gì tuyệt đối không được sai?" Câu trả lời thường là: đặt đơn hàng và thanh toán. Search product có thể chậm, trang catalog có thể cache 5 phút, nhưng checkout phải luôn hoạt động.

Điều này dẫn đến quyết định kiến trúc rất cụ thể:

  • Checkout service: synchronous, strong consistency, replicated database
  • Search service: async, eventual consistency, có thể stale 5 phút
  • Product catalog: heavily cached, CDN, acceptable nếu stale 1 tiếng

Khi bạn biết thứ gì critical, bạn đầu tư đúng chỗ. Không phải đầu tư đồng đều cho mọi thứ - điều đó vừa tốn kém vừa phức tạp không cần thiết.


Câu hỏi 4: "Data nào cần real-time, data nào có thể batch?"

Câu hỏi này tiết kiệm cho tôi rất nhiều phức tạp kiến trúc.

Ví dụ: Inventory management. Bạn có thực sự cần biết exact stock count real-time? Hay "còn hàng / hết hàng" cập nhật mỗi 5 phút là đủ?

Với 99% retailer, cập nhật mỗi 5 phút là fine. Bạn không cần event streaming pipeline phức tạp. Một batch job chạy mỗi 5 phút, read từ database, update cache là đủ.

Nhưng với flash sale trong 10 phút, bạn cần real-time. Vì 1000 người mua cùng lúc và stock chỉ còn 50 cái - thì batch 5 phút sẽ oversell.

Pattern tôi dùng:

// Xác định data category
// Category 1: Real-time required
//   - Order placement
//   - Payment processing
//   - Stock reservation (khi flash sale)

// Category 2: Near-real-time (< 5 phút)
//   - Inventory display
//   - Price updates
//   - Search index

// Category 3: Batch (giờ/ngày)
//   - Analytics
//   - Reports
//   - Email notifications

Khi bạn phân loại xong, kiến trúc tự nhiên đơn giản hơn rất nhiều.


Câu hỏi 5: "Budget vận hành hàng tháng là bao nhiêu?"

Câu hỏi này thường bị bỏ qua nhất - và cũng gây ra nhiều bất ngờ nhất sau khi deploy.

Tôi đã từng thiết kế hệ thống với 5 microservices trên Kubernetes, mỗi service 2 replicas. Chi phí Azure hàng tháng: khoảng $800-1000. Khách hàng budget $200/tháng.

Bây giờ câu hỏi về budget tôi hỏi ngay trong buổi discovery đầu tiên. Và từ con số đó, tôi work backwards để chọn kiến trúc phù hợp.

$50-100/tháng: Single App Service + Azure SQL (Standard tier) - đủ cho hầu hết SMB

$200-500/tháng: 2-3 App Services + SQL + Redis Cache - đủ cho hệ thống vừa

$1000+/tháng: Kubernetes, microservices, Event Hub - chỉ khi thực sự cần scale

Kiến trúc đẹp trên whiteboard nhưng vượt budget không phải kiến trúc tốt. Kiến trúc tốt là kiến trúc phù hợp với constraints thực tế.


Bài học tôi rút ra

Sau hơn 20 năm và nhiều dự án - cả thành công lẫn thất bại - tôi nhận ra: đa số lỗi kiến trúc không phải vì thiếu kiến thức kỹ thuật, mà vì thiếu thông tin về context.

5 câu hỏi này không phải magic. Chúng chỉ giúp bạn có đủ thông tin để đưa ra quyết định phù hợp. Và đôi khi, câu trả lời cho cả 5 câu hỏi sẽ dẫn bạn đến một monolith đơn giản chạy trên một server - và đó hoàn toàn là lựa chọn đúng.


Gửi các bạn trẻ

Khi bạn được giao thiết kế một hệ thống mới, đừng vội mở IDE hay vẽ diagram. Hãy hỏi trước.

Và khi bạn hỏi, hãy lắng nghe cả những gì người ta nói lẫn những gì người ta không nói. "Hệ thống cần nhanh" có thể nghĩa là "trang load 3 giây hiện tại khó chịu quá", chứ không phải "cần sub-100ms P99 latency".

Hiểu đúng vấn đề còn quan trọng hơn giải quyết đúng vấn đề.


Bạn nghĩ sao?

Bạn có câu hỏi nào khác mà bạn luôn hỏi trước khi bắt đầu dự án mới? Tôi rất muốn nghe - vì 5 câu của tôi chắc chắn chưa đủ :)


/Son Do - believe in basic

#1percentbetter #SolutionArchitecture #SystemDesign #softwareengineering


Bài viết liên quan

Xem thêm
Solution Architecture & System Design

PostgreSQL vs SQL Server - quyết định tôi đã đưa ra và tại sao

Không có database "tốt hơn". Có database phù hợp hơn với context của bạn. Tôi dùng SQL Server 20 năm và PostgreSQL 5 năm - cả hai đều excellent, nhưng chúng khác nhau ở những trade-off quan trọng mà architect cần hiểu rõ. Năm 2019, tôi nhận một project mới - một startup fintech đang xây MVP. Họ hỏi tôi: "Anh Son, chúng tôi nên dùng database gì?" Câu hỏi đơn giản. Nhưng tôi không trả lời ngay. Thay vào đó, tôi hỏi lại: "Tech stack của team là gì? Ai sẽ maintain database này sau khi tôi đi? Infrastructure của các bạn là on-premise hay cloud? Budget cho licensing là bao nhiêu?" Họ nhìn tôi hơi ngớ ngẩn. Họ expected một câu trả lời technical - benchmark performance, feature comparison. Tôi lại hỏi về organization và budget. Vì đó mới là thứ thực sự quyết định.

Solution Architecture & System Design

Conway's Law - tại sao architecture của bạn trông giống org chart

Conway's Law nói rằng hệ thống bạn build sẽ phản chiếu cấu trúc tổ chức của team. Đây không phải lý thuyết học thuật - đây là lý do tại sao microservices nhiều dự án VN thất bại, và tại sao đôi khi cần thay đổi org chart trước khi thay đổi architecture. Năm 2021, tôi bắt đầu làm tư vấn cho một công ty fintech. Họ muốn chuyển từ monolith sang microservices - xu hướng lúc đó ai cũng nói về. Tôi vào, review codebase, rồi nhìn sang org chart. Và tôi thấy ngay. Monolith của họ có 3 module lớn: Accounting, Lending, và Customer Management. Org chart của họ cũng có 3 team tương ứng: Team Kế toán, Team Tín dụng, và Team Khách hàng. Ba team này không nói chuyện với nhau nhiều - mỗi team có lead riêng, backlog riêng, sprint riêng. Tôi đoán trước microservices của họ sẽ trông như thế nào nếu họ tự migrate: đúng 3 service, tương ứng với 3 team. Không nhiều hơn, không ít hơn. Và đó chính xác là điều xảy ra sau 6 tháng họ tự làm trước khi gọi tôi vào. 3 services, ranh giới business không đúng, coupling vẫn còn đầy, chỉ là coupling giờ đi qua HTTP thay vì function call. Distributed monolith - thứ tệ nhất của cả hai thế giới. Conway's Law đã xảy ra, nhưng không ai để ý.