Chắc nhiều bạn cũng đã nghe nói đến 2 khái niệm Monolithic và Microservices trong cách tổ chức, xây dựng một ứng dụng rồi phải không? Trong bài viết này, mình sẽ điểm lại những ý tưởng cơ bản của 2 khái niệm này để những bạn chưa biết thì hiểu về nó, còn những bạn đã biết rồi thì có thể trao đổi thêm với mình về chúng, các bạn nhé!
Trước tiên, mình sẽ nói về khái niệm Monolithic trước. Đây là cách xây dựng một ứng dụng theo kiểu truyền thống, mà ở đó tất cả các chức năng, code của ứng dụng được đóng gói trong một package duy nhất.
Để xây dựng một ứng dụng, chúng ta thường có 3 phần: phần hiển thị giao diện cho người dùng (client-side), phần xử lý logic cho ứng dụng (server-side) và các hệ thống database mà ứng dụng của chúng ta sẽ kết nối tới. Phần server-side sẽ nhận request từ người dùng, xử lý logic, thao tác với database nếu có và trả về kết quả cho người dùng dưới dạng giao diện HTML. Theo ý tưởng của Monolithic thì tất cả các phần trên sẽ được đóng gói trong một package, những thay đổi của một trong 3 phần trên, đòi hỏi chúng ta có thể phải deploy lại toàn bộ ứng dụng.
Monolithic có thể tốt với những ứng dụng nhỏ khi mà ở đó các chức năng của ứng dụng ít, không đòi hỏi nhiều thời gian để làm quen khi những người mới làm việc với project đó. Nhưng nếu chức năng của ứng dụng ngày qua ngày càng phình to lên thì chúng ta phải xem lại. Bảo trì code sẽ ngày càng khó hơn, việc thay đổi code hoặc fix bug một chức năng nào đó đòi hỏi người code phải hiểu rõ về ứng dụng để không ảnh hưởng đến logic của những chức năng khác của ứng dụng.
Mình cũng đang gặp một trường hợp tương tự, khi mà project mình đang làm có kiến thức business logic quá nhiều và code quá phức tạp. Đòi hỏi những người mới vào phải có thời gian training nhiều, code design phức tạp đến nỗi những bạn mới ra trường mà vào project của mình, ai cũng than trời than đất. Và việc change code theo yêu cầu của khách hàng đòi hỏi mình phải take time nhiều để review code, xem việc thay đổi này có ảnh hưởng gì đến business của ứng dụng hay không?
Để giải quyết những bất cập trên, người ta đã giới thiệu mô hình Microservices. Với mô hình này, ứng dụng của chúng ta thay vì tất cả các chức năng, code được đóng gói trong 1 package duy nhất, bây giờ sẽ được chia ra theo kiểu có nhiều phần khác nhau, mỗi phần được gọi là service. Các service này sẽ trao đổi thông tin với nhau thông qua các API với các kết nối HTTP.
Tổng hợp các service này lại với nhau, chúng ta vẫn sẽ có một ứng dụng hoàn chỉnh theo nhu cầu của khách hàng nhưng theo kiểu Microservices.
Việc chia ra các service như thế nào theo Microservices sẽ tuỳ theo yêu cầu của ứng dụng, và sẽ do những người thiết kế ứng dụng đề xuất. Nhưng có những nguyên tắc mà bắt buộc mỗi service phải đáp ứng được đó là service đó phải có thể deploy độc lập được, không ảnh hưởng đến các ứng dụng khác và có thể mở rộng được một cách dễ dàng.
Một nhu cầu nữa có thể ảnh hưởng đến việc chia ra các service như thế nào đó là nhu cầu có thể sử dụng nhiều ngôn ngữ lập trình trong một hệ thống Microservices. Service này có thể dùng Java với Spring Boot, service kia có thể dùng NodeJS,…
Việc chia nhỏ ra như thế, các bạn thử hình dung, chúng ta sẽ có rất nhiều lợi ích, có thể kể ra đây như:
- Dễ bảo trì code
- Dễ hình dung được các chức năng của ứng dụng
- Dễ tiếp cận cho những người mới.
- Việc release các tính năng mới sẽ nhanh chóng nhờ vào việc sử dụng các cơ chế deployment CI/CD pipeline.
Tuy nhiên, cũng có một số khó khăn có thể xảy ra với nhiều người khi sử dụng Microservices đó là:
- Vì chúng ta chia nhỏ ứng dụng ra thành nhiều services nên có thể ít nhiều gây khó khăn trong việc quản lý các service đó.
- Việc chia nhỏ ra các service như thế nào, đôi khi cũng làm đau đầu cho các nhà thiết kế.
- Với những Microservices sử dụng nhiều công nghệ khác nhau thì đòi hỏi những người mới phải quen với những công nghệ đó thì mới có thể làm việc được.