Giới thiệu về Microservices

Một phần là dự án đang trong quá trình maintain, cần cải thiển performance và cũng là có chút hứng thú về mô hình microservice nên mình xin chia sẻ chút kiến thức về mảng này sau khi đọc xong chương 1 cuốn Microservices: From Design to Deployment

Trong cuốn sách có tổng cộng 7 chương sẽ đi từ việc design như thế nào cho đến việc deploying microservices như thế nào, đương nhiên là cả lợi ích lẫn hạn chế của mô hình này. Vậy thì bắt đầu chương đầu tiên nhé!

1.Building Monolithic Applications (Ứng dụng kiến trúc một khối)

Thường thì ta sẽ bắt đầu project với kiến trúc nguyên khối bởi tính đơn giản của nó khi phát triển và khi deploy. Với cấu trúc module hợp lý, đóng gói tất cả và cài đặt thành một khối, có thể nói là vừa có lợi vừa có hại. Lợi là bắt đầu đơn giản, nhanh gọn, nhưng càng về sau này khi ứng dụng có lượng truy cập và database lớn lên thì việc kiểm soát 1 module có bao nhiêu chức năng thật không đơn giản.

Cùng điểm qua một vài lợi ích cũng như khó khăn khi bạn cứ giữ dự án theo hướng monolithic từ đầu đến cuối:

Ưu điểm:

  • Là cách làm truyền thống nên sẽ không khó khăn khi bắt đầu, có sẵn nhiều framework để bắt đầu mà không cần phải suy nghĩ nhiều như: Rails, Django, NodeJs, ...
  • Với sự phát triển của các IDE và những công cụ tập trung vào xây dựng những ứng dụng trên template sẵn có
  • Ứng dụng kiểu này rất dễ scale bằng cách chạy nhiều instance được phân tải bằng load balancer (tải cân bằng)
  • Nó có thể xử lý các request dạng HTTP, thực hiện logic nghiệp vụ, truy cập cơ sở dữ liệu và có thể trao đổi dữ liệu với các hệ thống khác

Nhược điểm:

  • Theo thời gian thì project trở nên phức tạp và lớn dần. Các tính năng mới sẽ mất nhiều thời gian hơn để phát triển và tái cấu trúc các tính năng hiện có sẽ nhiều khó khăn hơn
  • Áp dụng công nghệ mới khó khăn vì toàn bộ ứng dụng phải thay đổi. Do đó nhiều ứng dụng một khối thường phụ thuộc một công nghệ cũ và lỗi thời
  • Không hề dễ để hiểu project do các module liên quan chặt chẽ lẫn nhau. Một issue nhỏ cũng có thể làm chết toàn bộ ứng dụng
  • Các service quan trọng không thể scale riêng dẫn đến lãng phí tài nguyên vì toàn bộ ứng dụng phải scale theo
  • Khi ứng dụng lớn, mỗi lần deploy phiên bản mới cũng sẽ là một cực hình

2. Microservice

Với những nhược điểm trên của cấu trúc monolithic thì việc phát triển lâu dài có vẻ không ổn nhỉ :3. Nhưng như vậy không phải là khuyên bạn nên cấu trúc theo hướng microservice ngay từ đầu, KHÔNG. Không nên bắt đầu ứng dụng theo hướng microservice làm gì cả, nghe thì có vẻ hấp dẫn nhưng việc đó rất nguy hiểm và dễ thất bại.

Nên là build dần dần monolithic application thành microservice bằng cách tách dần các features của nó ra thành từng API nhỏ (service). Theo thời gian, số lượng features sẽ giảm cho đến khi biến mất hoàn toàn hoặc chỉ còn là một feature nhỏ được thực hiện bởi một service khác. Đây cũng là ý tưởng chính của mô hình microservice.

Với ý tưởng chia nhỏ như vậy thì mỗi một microservice sẽ giống như là một cái app nhỏ nhỏ, xinh xinh vậy. Nó có thể chỉ là một đoạn logic nhỏ để tính tiền chẳng hạn.

Ví dụ: ứng dụng của bạn có chức năng chính là tình tiền cho toàn bộ nhân viên trong một tháng, sau này phát sinh thêm trường hợp là tháng 2 nhân viên đó đi làm 30 ngày. Thế bạn mí thắc mắc "wtf is that!!!" 😱 thằng này OT hay là do tháng 2 có 30 ngày? khó vãi, tách ra service riêng để xử lý trường hợp tháng 12 này => 1 microservice mới

Mỗi chức năng giờ được thực thi bởi một microservice. Ứng dụng web cũng có thể chia nhỏ hơn chuyên cho từng đối tượng người dùng. Thiết kế giao diện cho từng đối tượng người dùng giúp tối ưu trải nghiệm tốt hơn, tốc độ nhanh hơn, dễ tương thích hơn trong khi chức năng tối giản hơn.

Ứng dụng của người dùng cuối sẽ không được kết nối trực tiếp vào back-end services. Thay vào đó có API gateway đứng giữa. Nó đóng vai trò như 1 cửa ngõ chung để các ứng dụng bên ngoài gọi vào các microservice bên trong. Các microservice gọi trực tiếp nhau không thông qua API Gateway. Vấn đề là làm thế nào để các microservice (và cả API Gateway) biết được thông tin của microservice khác để gọi. Khi đó trong hệ thống cần có 1 thành phần gọi là Service Discovery - CHƯƠNG 2 (một loại API Gateway phổ biến như [Kong Gateway])(https://konghq.com/kong/)).

Kiến trúc Microservices ảnh hưởng lớn đến quan hệ ứng dụng và cơ sở dữ liệu. Thay vì dùng chung một cơ sở dữ liệu giữa các service, mỗi service sẽ có cơ sở dữ liệu riêng. Cách này đi ngược lại việc tập trung hóa cơ sở dữ liệu trong truyền thống, nên nếu thấy rắc rối thì cũng có thể tìm cách trỏ đến DB chính của ứng dụng gốc thôi cũng khả thi.

Đặc biệt trong cấu trúc microservice là từng microservice sẽ có thể tùy chọn một công nghệ mới hoàn toàn hoặc update framework cũ lên version mới nhất miễn là phù hợp và tối ưu là được.

Nhìn một cách tổng thể, kiến trúc microservice tương tự như SOA(Service - Oriented Architecture). Cả 2 đều là một tập các service được kết nối với nhau. Điểm khác là microservices không dùng chuẩn do các tập đoàn lớn như IBM, Microsoft, Oracle đặt ra như web service specificcations (WS-*) hay Enterprise Service Bus (ESB).

Phân tích khá là loằng ngoằng nên ta sẽ đi tóm lược lại ưu nhược điểm của mô hình microservice luôn.

Ưu điểm:

  • Đơn giản hóa hệ thống, kiến trúc lại các features lớn (chia nhỏ) làm nhiều service nhỏ để dễ dàng quản lý hơn.
  • Tự do lựa chọn technical cho mỗi service nhỏ để phát triển
  • Các services có thể được phát triển, test, deploy và scale độc lập mà không ảnh hưởng đến các services khác.
  • Thêm nữa, có thể tối ưu chi phí vận hành service bằng cách triển khai mỗi service lên một resource thích hợp. Ví dụ: bạn có thể deploy iamges lên server EC2 sử dụng Compute Optimized instances, ngoài ra nhu cầu về sử dụng RAM cũng có thể tìm kiếm EC2 Memory-optimized intansces

Nhược điểm:

  • Chia nhỏ cũng sẽ dẫn đến nhưng service bị thừa(không nhất thiết phải tách), vụn vặt + khó kiểm soát
  • Distributed system (hệ thống phân tán). Lập trình viên cần phải lựa chọn phát triển mỗi service nhỏ giao tiếp với các service khác bằng cách nào messaging hay là RPC. Hơn thế nữa, họ phải xử lý sự cố khi kết nối chậm, lỗi khi thông điệp không gửi được hoặc thông điệp gửi đến nhiều đích đến vào các thời điểm khác nhau.
  • Testing một service trong kiến trúc microservices đôi khi yêu cầu phải chạy cả các service nhỏ khác mà nó phụ thuộc. Do đó khi phân rã ứng dụng một khối thành microservices cần luôn kiểm tra mức độ ràng buộc giữa các service. Nếu các service nhỏ cứ phụ thuộc vào nhau theo chuỗi, A gọi B, B gọi C, C lại gọi D. Nếu cứ như vậy thì việc bảo trì, kiểm thử sẽ có độ phức tạp tương tự - hoa hết cả mắt. Cho nên thiết kế service tốt sẽ giảm tối đa ảnh hưởng tới service khác.
  • Deploy ứng dụng hướng microservice cũng khác phức tạp. Nếu như mô hình monolithic chỉ cần bổ sung các server mới giống hệt nhau đằng sau load balancer. Thì microservice các service sẽ nằm trên nhiều máy ảo hay Docker container khác nhau. Như NetFlix hiện có hơn 700 services(2019). Vậy phải cần thiết bị có cơ chế phát hiện service để tự động cập nhật địa chỉ IP và cổng, mô tả, phiên bản của mỗi service

3.Tổng kết

Nếu ứng dụng của bạn chỉ ở quy mô nhỏ thì đừng nên nghĩ tới microservice làm gì cho đau đầu, hãy cứ mô hình monolithic đơn giản, gọn nhẹ, mà hiệu quả :3. Còn với những ứng dụng có lượng truy cập lớn hay là các chức năng xử lý logic phức tạp thì microservice là lựa chọn cũng phức tạp không kém :v, nhưng nó phù hợp 😃) để phát triển lâu dài

Túm váy lại thì sau khi đọc qua ebook và tham khảo các blog trên mạng mình có 1 vài lưu ý khi triển khai mô hình microservice như là:

  1. Đây có phải là sản phẩm phát triển lâu dài hay không?
  2. Mức độ scale của hệ thống có lớn không (scale về lượng người dùng hoặc về dữ liệu)?
  3. Chịu khó hay không :3

Thanks for reading!

All Rights Reserved