← Blog
Foundations

Chuyến đi của tôi tới "địa ngục Microservices" (Vì sao tôi thường chọn Monolith)

Thien Nguyen · Jun 23, 2026
Chuyến đi của tôi tới "địa ngục Microservices" (Vì sao tôi thường chọn Monolith)

Là một kiến trúc sư, tôi từng chứng kiến nhiều đội hào hứng nhảy vào microservices, bị thuyết phục bởi giấc mơ "scale vô hạn" và "đội nào tự lo việc nấy".

Và tôi cũng chứng kiến chính những đội đó một năm sau, ngụp lặn trong mớ phức tạp, tự hỏi vì sao thêm một tính năng mới lại mất tới sáu tuần.

"Địa ngục Microservices" là có thật, và tiền thuê nhà ở đó không hề rẻ.

Đó là trạng thái bạn rơi vào khi phần đường ống kỹ thuật trở nên phức tạp hơn gấp bội so với chính phần logic nghiệp vụ mà nó đáng lẽ phải phục vụ.

Từ những gì bản thân đã trải qua, đây là bức tranh chân thực về hành trình xuống địa ngục đó.


1. Cơn đau đầu mang tên "Eventual Consistency" (hay là cái chết của ACID)

Thứ đầu tiên giáng vào mặt bạn là database.

Tôi nhớ một dự án có một luồng cực kỳ quan trọng: Tạo đơn hàngCập nhật tồn khoXử lý thanh toán.

Trong một monolith, đây chỉ là một transaction database duy nhất, gọn gàng và đẹp đẽ. Nó nguyên tử (atomic). Nó an toàn. Và nó cứ thế chạy.

Còn trong microservices, giờ đây nó là 3 service, nhiều khả năng đi kèm 3 database riêng biệt. Bạn không thể có một transaction nữa.

Bạn buộc phải tự tay viết thêm logic bù trừ (người ta gọi sang là Saga, nhưng về bản chất nó chỉ là "code để dọn dẹp hậu quả của code").

Cái "logic bù trừ" này là một ổ bug khổng lồ. Bạn giờ sống ở miền đất của "eventual consistency", một cách nói lịch sự cho câu:

"Dữ liệu của bạn hiện đang sai, nhưng chắc là bọn tôi sẽ sửa được thôi… sớm muộn gì đó."

Với bất kỳ hệ thống FinTech hay HealthTech nào, điều này là không thể chấp nhận.

(Nhiều đội "lách" bằng cách dùng chung một database. Đừng làm thế. Bạn vừa tạo ra một con quái vật ẩn mình, một điểm chết duy nhất cho cả hệ thống.)


2. Thuế mạng (hay là "Lời gọi hàm của tôi giờ thành một con bug")

Khi bạn đánh đổi những lời gọi hàm in-memory đáng tin cậy để lấy những lời gọi HTTP chập chờn, bạn phải trả một khoản thuế rất nặng.

Mọi lập trình viên trong đội của bạn, dù muốn hay không, giờ đều phải trở thành chuyên gia về hệ phân tán.

Từng. Lời gọi. Một. đều phải xử lý:

Timeout: Chuyện gì xảy ra khi UserService đơn giản là… không thèm trả lời?

Retry: Nếu bạn gọi lại, liệu request đó có idempotent không? Xin chúc mừng, bạn vừa trừ tiền khách hàng hai lần.

Circuit Breaker: Bạn bắt buộc phải cài đặt thứ này để một service đã chết (InventoryService) không kéo theo mọi service khác gọi tới nó cùng chết chùm.

Tải nhận thức (cognitive load) tăng vọt.

Tôi từng thấy những đội 10 kỹ sư cố gồng gánh 40 service. Bạn vừa dựng lại đúng cái monolith cũ của mình, nhưng lần này nối với nhau qua một đường mạng ì ạch.


3. Thuế observability

Đây mới là phần bóp chết tốc độ. Còn nhớ cái thời bạn chỉ có một file log duy nhất không? Những ngày tháng tươi đẹp.

Giờ đây, một cú click của người dùng có thể đi qua 10 service khác nhau. Khi nó lỗi, bạn không còn debug nữa; bạn đang chơi một ván Cờ tỷ phú truy tìm thủ phạm trên quy mô phân tán.

Trước khi kịp viết được dòng tính năng nào, bạn đã phải nộp khoản "thuế observability":

Distributed Tracing (ví dụ Jaeger)

Centralized Logging (ví dụ ELK Stack)

Metrics Aggregation (ví dụ Prometheus)

Và đây không chỉ là vấn đề trên production; nó còn phá nát luôn môi trường phát triển của bạn.

Làm sao bạn chạy nổi 40 service trên laptop của một lập trình viên? Test E2E kiểu gì đây?


4. Địa ngục con người và quản lý

Nhưng khoản thuế tệ nhất lại chẳng phải kỹ thuật. Đó là thuế con người.

Tỷ lệ kỹ sư trên service vượt khỏi tầm kiểm soát: Tôi từng thấy mỗi kỹ sư ôm 4-5 service. Đây không phải "tự chủ"; đây là "kiệt sức". Một người giờ vừa là người vận hành, người debug, vừa trực on-call cho cả nửa tá hệ thống.

"Resume-Driven Development": Khi "tự chủ" biến thành "vô chính phủ", bạn sẽ có một service viết bằng Kotlin, một cái bằng Go, và một cái bằng Rust mà chỉ duy nhất một người hiểu. Đến khi người đó nghỉ việc, bạn đã "bỏ rơi" một phần hệ thống của mình.

Kiến trúc phản chiếu sơ đồ tổ chức: Điều này ổn… cho tới khi công ty tái cơ cấu. Mà công ty thì lúc nào cũng tái cơ cấu. Đột nhiên đội "Payments" bị tách ra, nhưng toàn bộ hạ tầng của bạn lại rối như tơ vò. Bạn vừa tự nguyện đăng ký một dự án migration không mang lại chút giá trị nào cho khách hàng.


Vậy… khi nào thì cái monolith "nhàm chán" (làm cho đúng) lại tốt hơn hẳn?

Một Modular Monolith được thiết kế tử tế (các module tách bạch, chung một codebase) không hề là "đồ cổ". Nó là một lựa chọn thực dụng, và thường là lựa chọn vượt trội.

Theo kinh nghiệm của tôi, monolith thắng tuyệt đối trong những trường hợp sau:

1. Khi toàn vẹn giao dịch (ACID) là vua: Nếu bạn đang xây FinTech, HealthTech hay một hệ ERP phức tạp, nghiệp vụ của bạn bắt buộc phải nhất quán 100%. Sự tin cậy của một transaction database thực thụ là điều không thể đem ra mặc cả.

2. Khi bạn là một sản phẩm giai đoạn đầu (tốc độ ra thị trường là vua): Rủi ro lớn nhất của bạn không phải là scale; mà là làm nhầm thứ cần làm. Một Modular Monolith cho phép bạn đi nhanh đến kinh ngạc. Refactor bên trong một monolith dễ hơn gấp 100 lần so với refactor 10 microservices.

3. Khi bạn là một đội nhỏ đến vừa (1-20 kỹ sư): Microservices là công cụ để giải bài toán scale con người. Nếu bạn chỉ là một đội, microservices sẽ giết chết tốc độ của bạn.

4. Khi bạn chưa có một đội Platform chuyên trách: Chọn microservices mà không có đội SRE/Platform thì chẳng khác nào mua xe đua Công thức 1 để đi chợ. Đắt đỏ, khó lái, và kiểu gì bạn cũng đâm xe.


Lời khuyên cuối cùng của tôi

Hãy bắt đầu bằng một Modular Monolith.

Thiết kế nó với ranh giới rõ ràng, giao tiếp qua interface, và tuyệt đối không dùng chung bảng database giữa các module.

Cách này mang lại cho bạn 90% lợi ích của microservices (sự tách bạch) với chỉ 10% chi phí vận hành.

Chỉ tách một module ra thành microservice riêng khi bạn có một lý do rõ ràng, đủ đau, và hiển nhiên.

Microservices là một bước refactor, không phải điểm khởi đầu.


Khám phá thêm nhiều bài phân tích chuyên sâu và xu hướng công nghệ tại digitalam.org.