Monolith hay microservices? Cách chọn kiến trúc không theo trào lưu

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Microservices từng được nhắc đến như đích đến tất yếu của mọi hệ thống nghiêm túc. Thực tế, nhiều đội nhóm đã gặp rắc rối khi chia nhỏ quá sớm. Bài này giúp bạn hiểu hai hướng kiến trúc, đánh đổi của từng bên và cách quyết định thực dụng.

Monolith là gì?

Monolith là ứng dụng được xây và triển khai như một khối duy nhất: giao diện, logic nghiệp vụ, truy cập dữ liệu cùng nằm trong một codebase và chạy cùng nhau. Đây là cách hầu hết dự án bắt đầu, và nhiều sản phẩm thành công chạy trên monolith nhiều năm.

  • Ưu điểm: đơn giản để phát triển, kiểm thử, gỡ lỗi và triển khai; gọi hàm trực tiếp rất nhanh và đáng tin; một transaction database cho mọi nghiệp vụ.
  • Nhược điểm: khi quá lớn, build và triển khai chậm, nhiều nhóm dẫm chân nhau, khó mở rộng riêng từng phần, và một lỗi có thể ảnh hưởng toàn bộ.

Microservices là gì?

Hệ thống được chia thành nhiều dịch vụ nhỏ, độc lập, mỗi dịch vụ lo một khả năng nghiệp vụ (đơn hàng, thanh toán, người dùng...), có codebase, thường cả database riêng, và giao tiếp qua mạng (HTTP, gRPC, hàng đợi thông điệp).

  • Ưu điểm: triển khai và mở rộng độc lập từng dịch vụ, nhóm tự chủ, có thể chọn công nghệ phù hợp, lỗi được cô lập tốt hơn nếu thiết kế đúng.
  • Nhược điểm: độ phức tạp vận hành lớn (nhiều dịch vụ để triển khai, giám sát, bảo mật), gọi qua mạng chậm và có thể lỗi, mất transaction đơn, khó gỡ lỗi xuyên dịch vụ, cần kỹ năng DevOps tốt.

Cái giá của "phân tán"

Khi một lời gọi hàm biến thành lời gọi mạng, bạn phải đối mặt với độ trễ, mất kết nối, thời gian chờ, thử lại, và thông điệp có thể đến trùng hoặc không đến. Dữ liệu được chia ra nhiều database nên truy vấn nối bảng và transaction truyền thống không còn; bạn cần các mẫu như saga và nhất quán cuối cùng. Cần thêm theo dõi phân tán (distributed tracing), tập trung log, kiểm tra sức khỏe, khám phá dịch vụ. Đó là khoản đầu tư lớn.

Modular monolith: con đường ở giữa

Nhiều đội chọn xây một monolith nhưng chia thành các module có ranh giới rõ ràng: mỗi module có API công khai riêng, không truy cập thẳng vào dữ liệu nội bộ của nhau. Bạn được lợi từ sự đơn giản vận hành của monolith, đồng thời giữ cấu trúc để sau này tách module nào cần thiết thành dịch vụ riêng. Đây thường là điểm khởi đầu hợp lý cho đa số sản phẩm.

Dấu hiệu bạn có thể cần tách dịch vụ

  1. Một phần của hệ thống cần mở rộng khác hẳn phần còn lại (ví dụ xử lý ảnh nặng, tìm kiếm).
  2. Nhiều nhóm lớn liên tục xung đột khi cùng sửa một codebase và phải chờ nhau phát hành.
  3. Một phần có yêu cầu tin cậy, bảo mật hoặc công nghệ riêng biệt.
  4. Chu kỳ triển khai của các phần cần độc lập thật sự.

Nếu đội của bạn vài người và sản phẩm còn đang tìm hướng đi, các dấu hiệu trên hầu như chưa xuất hiện, và microservices sẽ chỉ làm bạn chậm lại.

Nguyên tắc nếu quyết định tách

  • Tách theo ranh giới nghiệp vụ (khái niệm miền), không theo lớp kỹ thuật như "dịch vụ database".
  • Mỗi dịch vụ sở hữu dữ liệu của mình; tránh nhiều dịch vụ cùng ghi vào một database.
  • Tách dần từng phần (mẫu strangler), đừng viết lại toàn bộ trong một lần.
  • Đầu tư công cụ trước: CI/CD, giám sát, tập trung log, tracing.
  • Thiết kế cho lỗi: timeout, thử lại có backoff, cầu dao (circuit breaker).

Câu hỏi nên tự hỏi trước khi quyết định

Trước khi chia nhỏ hệ thống, hãy trả lời trung thực vài câu: đội của tôi có bao nhiêu người và họ có thực sự bị cản trở bởi codebase chung không? Chúng tôi đã có quy trình triển khai tự động và giám sát đủ tốt cho một dịch vụ chưa? Vấn đề hiện tại là kiến trúc, hay chỉ là code chưa gọn và thiếu kiểm thử? Rất nhiều khi nguyên nhân thật nằm ở chất lượng code và quy trình, và chia thành microservices chỉ chuyển cái rối từ trong code ra thành rối giữa các dịch vụ, khó sửa hơn nhiều. Việc dọn dẹp ranh giới module trong monolith luôn là bước tiền đề đáng làm, dù cuối cùng bạn có tách dịch vụ hay không.

Kết luận

Không có kiến trúc "đúng" tuyệt đối, chỉ có kiến trúc phù hợp với quy mô đội ngũ, giai đoạn sản phẩm và năng lực vận hành. Lời khuyên an toàn: bắt đầu bằng monolith có module rõ ràng, đo nỗi đau thật, và chỉ tách khi lợi ích vượt chi phí. Kiến trúc tốt là kiến trúc giúp đội của bạn giao sản phẩm nhanh và ổn định, không phải kiến trúc gây ấn tượng nhất trên sơ đồ.

Nếu muốn luyện tập cùng bài tập thực tế, hãy ghé các khóa học tại codebem.com khi bạn sẵn sàng.

author_photo
Nguyễn Đình Cường

0 comment