Bài 4: Microservices Và Monolith

Bài 4: Microservices Và Monolith: So Sánh Chi Tiết Qua Ví Dụ Thực Tế

Ở bài trước, bạn đã tạo thành công microservice đầu tiên với Node.js. Hôm nay, mình muốn chúng ta cùng đi sâu hơn một chút để so sánh microservices với cách làm truyền thống, gọi là monolith. Mình biết ở bài 1, mình đã giới thiệu sơ qua về sự khác biệt giữa hai cách này, nhưng lần này, mình sẽ dùng một ví dụ cụ thể để bạn thấy rõ hơn ưu điểm và nhược điểm của từng cách. Mình sẽ kể câu chuyện về một dự án nhỏ mà mình từng làm, để bạn dễ hình dung hơn. Sau bài này, bạn sẽ biết khi nào nên dùng microservices, khi nào nên dùng monolith. Sẵn sàng chưa nào?

Dự Án Ví Dụ: Xây Dựng Ứng Dụng Đặt Đồ Ăn Online

Hãy tưởng tượng bạn và mình cùng làm một ứng dụng đặt đồ ăn online, giống như một phiên bản đơn giản của GrabFood hay ShopeeFood. Ứng dụng này cần có các chức năng sau:

  • Hiển thị danh sách món ăn (menu).
  • Cho phép người dùng đặt món (order).
  • Xử lý thanh toán (payment).

Mình sẽ xây dựng ứng dụng này theo hai cách: một lần dùng monolith, một lần dùng microservices. Sau đó, chúng ta sẽ so sánh xem cách nào phù hợp hơn trong từng tình huống.

Cách 1: Xây Dựng Ứng Dụng Với Monolith

Đầu tiên, mình thử xây dựng ứng dụng này theo cách monolith – nghĩa là tất cả chức năng được gom vào một ứng dụng duy nhất.

  • Cách làm: Mình viết một ứng dụng Node.js lớn, chứa tất cả: hiển thị menu, xử lý đơn hàng, và thanh toán. Mọi thứ đều nằm trong một thư mục dự án, dùng chung một cơ sở dữ liệu (VD: MySQL). Khi người dùng truy cập, ứng dụng sẽ xử lý toàn bộ yêu cầu từ đầu đến cuối.
  • Ưu điểm:
    • Dễ phát triển ban đầu: Vì mọi thứ ở một chỗ, mình không cần lo về việc kết nối giữa các phần. Mình chỉ cần viết code, chạy, và kiểm tra.
    • Dễ quản lý cho dự án nhỏ: Với một ứng dụng nhỏ như thế này, mình chỉ cần một server để chạy, không cần nhiều công cụ phức tạp.
  • Nhược điểm:
    • Khó mở rộng: Khi số lượng người dùng tăng (VD: 10.000 người cùng đặt món), mình phải nâng cấp cả server, dù chỉ phần thanh toán bị quá tải.
    • Lỗi ảnh hưởng toàn bộ: Nếu tính năng thanh toán bị lỗi, cả ứng dụng có thể dừng lại, làm gián đoạn cả việc hiển thị menu và đặt món.
    • Khó làm việc nhóm: Nếu có nhiều người cùng làm, mọi người phải làm việc trên cùng một codebase, dễ gây xung đột.

Mình từng làm một dự án monolith như thế này cho một quán ăn nhỏ. Ban đầu, mọi thứ rất ổn vì chỉ có vài chục khách mỗi ngày. Nhưng khi quán mở rộng và có hàng nghìn khách, hệ thống bắt đầu chậm, và mỗi lần cập nhật đều phải dừng toàn bộ ứng dụng. Điều này khiến khách hàng phàn nàn rất nhiều.

Cách 2: Xây Dựng Ứng Dụng Với Microservices

Bây giờ, mình thử xây dựng lại ứng dụng này theo cách microservices – nghĩa là tách thành các dịch vụ nhỏ, độc lập.

  • Cách làm: Mình tách ứng dụng thành 3 microservices:
    • Menu Service: Hiển thị danh sách món ăn, dùng MongoDB để lưu dữ liệu món ăn.
    • Order Service: Xử lý đơn hàng, dùng MySQL để lưu đơn hàng.
    • Payment Service: Xử lý thanh toán, tích hợp với một cổng thanh toán (VD: Stripe). Mỗi microservice chạy riêng, giao tiếp với nhau qua API. Ví dụ, khi người dùng đặt món, Order Service sẽ gọi Menu Service để lấy danh sách món, sau đó gọi Payment Service để thanh toán.
  • Ưu điểm:
    • Dễ mở rộng: Nếu phần thanh toán bị quá tải, mình chỉ cần thêm server cho Payment Service, không ảnh hưởng đến các dịch vụ khác.
    • Lỗi không lan rộng: Nếu Payment Service lỗi, người dùng vẫn có thể xem menu và đặt món, chỉ phần thanh toán bị ảnh hưởng.
    • Dễ làm việc nhóm: Mỗi team có thể phụ trách một microservice, không đụng chạm nhau.
  • Nhược điểm:
    • Phức tạp hơn: Mình phải quản lý 3 microservices, cần công cụ để theo dõi và kết nối chúng (VD: API, message queue).
    • Cần nhiều tài nguyên: Mỗi microservice cần server riêng, tốn chi phí hơn so với monolith.

Sau khi chuyển sang microservices, dự án của quán ăn mà mình kể ở trên đã cải thiện rất nhiều. Khi khách hàng tăng, mình chỉ cần mở rộng Payment Service, và hệ thống không còn bị gián đoạn. Tuy nhiên, mình cũng mất nhiều thời gian hơn để thiết lập ban đầu, vì phải đảm bảo các microservices “nói chuyện” với nhau đúng cách.

So Sánh Nhanh: Microservices Và Monolith

Microservices-Architecture

Mình sẽ tóm tắt sự khác biệt qua một danh sách ngắn để bạn dễ hình dung:

  • Mở rộng hệ thống
    Microservices: Chỉ mở rộng phần cần thiết (VD: thêm server cho thanh toán).
    Monolith: Phải mở rộng toàn bộ, tốn tài nguyên.

  • Xử lý lỗi
    Microservices: Lỗi chỉ ảnh hưởng một phần, dễ sửa.
    Monolith: Lỗi có thể làm sập cả hệ thống.

  • Phát triển ban đầu
    Monolith: Dễ làm, ít phức tạp.
    Microservices: Cần thiết lập nhiều, phức tạp hơn.

  • Làm việc nhóm
    Microservices: Mỗi team làm một phần, ít xung đột.
    Monolith: Cả team làm chung, dễ gây rối.

Khi Nào Nên Dùng Microservices, Khi Nào Dùng Monolith?

Dựa trên ví dụ này, mình rút ra một số kinh nghiệm:

  • Dùng Microservices khi: Bạn làm hệ thống lớn, cần mở rộng nhanh, hoặc có nhiều team cùng làm (VD: ứng dụng như Grab, Shopee). Microservices giúp bạn xử lý tải lớn và làm việc hiệu quả hơn.
  • Dùng Monolith khi: Bạn làm dự án nhỏ, không cần mở rộng nhiều, hoặc mới bắt đầu (VD: một website bán hàng nhỏ). Monolith đơn giản hơn, tiết kiệm thời gian.

Câu Hỏi Trắc Nghiệm: Kiểm Tra Hiểu Biết Của Bạn

Hãy thử trả lời vài câu hỏi để xem bạn đã nắm được chưa nhé:

  1. Nếu một phần của hệ thống bị lỗi, cách nào ít ảnh hưởng hơn?
    A. Monolith
    B. Microservices
    Đáp án: B. Microservices – vì lỗi chỉ ảnh hưởng một dịch vụ, không làm sập toàn bộ.

  2. Khi nào nên dùng monolith?
    A. Hệ thống lớn, nhiều người dùng
    B. Dự án nhỏ, ít người dùng
    Đáp án: B. Dự án nhỏ, ít người dùng – vì monolith dễ làm và quản lý.

  3. Microservices có nhược điểm gì?
    A. Khó mở rộng
    B. Phức tạp hơn
    Đáp án: B. Phức tạp hơn – vì cần quản lý nhiều dịch vụ.

Kết Thúc: Bạn Đã Hiểu Rõ Hơn Về Microservices

Hôm nay, bạn đã thấy microservices và monolith khác nhau ra sao qua ví dụ thực tế về ứng dụng đặt đồ ăn. Mình hy vọng bạn đã hình dung được khi nào nên dùng cách nào. Ở bài tiếp theo, chúng ta sẽ học cách kết nối các microservices với nhau bằng API – một bước quan trọng để chúng “nói chuyện” với nhau. Hẹn gặp bạn ở bài sau nhé!

Điều hướng chuỗi bài viết<< Bài 3: Viết Microservice Đầu Tiên
>> Bài 5: Giao Tiếp Giữa Microservices
Article Thumbnail
Article Thumbnail
Datadog Webinar: Modernize AWS Logs at Scale
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận