Featured image of post Monolith vs. Microservices: Mô hình tư duy 'Biệt thự vs Ngôi làng'

Monolith vs. Microservices: Mô hình tư duy 'Biệt thự vs Ngôi làng'

Microservices có phải chỉ là sự cường điệu (hype)? Hướng dẫn chuyên sâu về 'Distributed Monolith', cái giá của Latency, và khi nào thì thực sự nên tách service.

“Bọn em đang plan viết lại con Monolith này sang Microservices.”

Câu nói này đã bức tử nhiều startup hơn cả việc không tìm được thị trường (product-market fit).

Anh em Dev thích Microservices vì nó trông ngầu như Netflix. Sếp và Business ghét Microservices vì tính năng mới tự nhiên mất gấp 3 lần thời gian để dev.

Đây là Hướng dẫn chuyên sâu về Kiến trúc. Chúng ta sẽ tìm hiểu tại sao Monolith thường lại tốt hơn, và thời điểm chính xác bạn nên chuyển đổi.


Phần 1: Nền tảng (Mô hình tư duy)

Monolith = Căn Biệt thự Lớn

Tưởng tượng một Biệt thự khổng lồ nơi mọi người sống chung (Auth, Thanh toán, User, Đơn hàng).

  • Giao tiếp: Tức thì. Đầu bếp cần Quản gia, gọi với một tiếng là xong. (Gọi hàm trong RAM: Nanoseconds).
  • Database: Một cái tủ lạnh khổng lồ. Mọi người dùng chung nguyên liệu.
  • Deploy: Bạn muốn sửa cái mái nhà? Phải đuổi tất cả mọi người ra ngoài 1 ngày để sửa. (Deploy lại toàn bộ app).
  • Rủi ro: Nếu Bếp cháy, cả Biệt thự cháy rụi.

Microservices = Ngôi làng

Tưởng tượng một Ngôi làng gồm các ngôi nhà nhỏ riêng biệt.

  • Giao tiếp: Chậm. Đầu bếp phải đi bộ sang nhà Quản gia để xin muối. (Gọi qua mạng: Milliseconds).
  • Database: Mỗi nhà có một tủ lạnh mini riêng. Cấm sang nhà nhau lấy đồ.
  • Deploy: Bạn sửa mái nhà ông Quản gia, ông Đầu bếp vẫn nấu ăn bình thường. Scale độc lập.
  • Rủi ro: Nếu nhà bếp cháy, cả làng vẫn an toàn… nhưng giờ thì chẳng ai có cơm ăn.

Phần 2: Điều tra (Chi phí ẩn)

Chuyển sang Microservices không miễn phí. Bạn đang đánh đổi Sự phức tạp của Code lấy Sự phức tạp của Vận hành (Ops).

1. Thuế Latency (Độ trễ)

Trong Monolith, hàm UserService.getUser() tốn 0.0001ms (Truy cập RAM). Trong Microservices, HTTP GET /users/1 tốn 20ms (Serialize mạng + TCP handshake + Latency đường truyền).

Bạn vừa làm cho thao tác cơ bản chậm đi 200,000 lần.

2. Ác mộng Truy vết (Tracing)

Trong Monolith, nếu lỗi, bạn xem Stack Trace. Nó báo chính xác dòng 42 bị lỗi.

Trong Microservices: Request -> Gateway -> Auth Service -> Order Service -> Payment Service (Lỗi). Log nằm ở đâu? Bạn phải lục tung 4 con server khác nhau để tìm.

  • Giải pháp: Bắt buộc phải cài Distributed Tracing (OpenTelemetry/Jaeger). Không có nó là mù dở.

Phần 3: Chẩn đoán (Distributed Monolith)

Đây là kiểu kiến trúc tồi tệ nhất trần đời.

Nó xảy ra khi bạn xây một Ngôi làng, nhưng lại sống theo kiểu Biệt thự.

  • Triệu chứng: “Em không deploy được Service A vì nó cần Service B update code trước.” (Coupling chặt).
  • Triệu chứng: Service A chọc thẳng vào Database của Service B để lấy dữ liệu. (Phá vỡ quy tắc Tủ lạnh riêng).
  • Triệu chứng: API call chằng chịt. Để load cái trang chủ, Frontend phải gọi 50 cái API tới 50 service.

Nếu service của bạn “Micro” (nhỏ) nhưng dính chặt vào nhau, bạn đã tạo ra một cục Distributed Monolith. Bạn gánh chịu toàn bộ sự chậm chạp của Microservices mà chẳng hưởng được tí lợi ích độc lập nào.


Phần 4: Giải pháp (Khi nào nên tách?)

Đừng tách vì kích thước (“Code base to quá rồi”). Hãy tách vì Nghiệp vụ (Domain).

Quy tắc Hai chiếc Pizza (Amazon)

Nếu một team quá đông, ăn 2 cái pizza không đủ, thì tách team. Sau đó hãy tách phần mềm để khớp với team đó.

Chiến thuật chia tách

  1. Luôn bắt đầu với Monolith. Nó giúp bạn đi nhanh giai đoạn đầu.
  2. Tách cái Nặng nhất trước.
    • Module “Xử lý ảnh” ngốn 90% CPU? Tách riêng nó ra (Lambda/Worker).
    • Giữ lại mọi thứ khác trong Monolith.
  3. Tách theo Vòng đời (Lifecycle).
    • Module “Billing” (Thanh toán) chỉ sửa 1 năm 1 lần, nhưng “Frontend” sửa hàng ngày? Tách Billing ra để đỡ lỡ tay làm hỏng chức năng thu tiền khi đang sửa CSS.

Mô hình tư duy chốt hạ

1
2
3
4
Monolith      -> Biệt thự. Nhanh, dễ chia sẻ, nhưng sợ sửa chữa lớn.
Microservices -> Ngôi làng. Giao tiếp chậm, bền vững, dễ sửa từng căn.

Distributed Monolith -> Ngôi làng mà mọi người bị còng tay vào nhau. Địa ngục trần gian.

Trừ khi bạn cần scale TỔ CHỨC (con người), hãy giữ lại MONOLITH (code). Bạn không phải Netflix. Bạn không cần rước cái khổ của Netflix vào thân làm gì.

Được tạo với sự lười biếng tình yêu 🦥

Subscribe to My Newsletter