Các mẫu kiến trúc phần mềm phổ biến bạn cần biết?

Mẫu kiến trúc phần mềm (Architectural pattern) là các kiến trúc thiết kế hệ thống đã được chứng minh từ các dự án thực tế và được tận dụng như là tham chiếu để sử dụng trong các dự án tương tự. Các kiến trúc sư phần mềm đã tìm cách để đúc kết và sử dụng lại các kiến thức về kiến trúc đã được ứng dụng thành công trong thời gian trước đó. Bài viết này lấy nguồn cảm hứng từ cuốn sách “Common Software Architectural Patterns you need to know” của Paul Clements and Rick Kazman.

Mẫu kiến trúc được định nghĩa là:

  • Một tập hợp các quyết định thiết kế được tìm thấy nhiều lần trong quá khứ
  • Có những đặc tính được định nghĩa tốt có thể sử dụng lại
  • Được mô tả như là trường class của kiến trúc
1. Software Application N-tier (Layered) Architecture design ...

Phát triển một kiến trúc có thể được xem như là quá trình lựa chọn, may đo và kết hợp giữa các mẫu pattern. Các kiến trúc sư phần mềm phải quyết định lựa chọn các mẫu thiết kế, làm thế nào để cho nó phù hợp với các ngữ cảnh cụ thể và các ràng buộc của vấn đề.

Trong bài viết này, tôi sẽ trình bày với các bạn về các mẫu kiến trúc được sử dụng rộng rãi trong các dự án thực tế trên thế giới.

Kiến trúc module (module pattern)

Kiến trúc phân lớp (Layerd pattern)

Là dạng kiến trúc rất phổ biến ngày nay, chắc chắn ai cũng đã từng nghe qua về kiến trúc 3 lớp, MVC, MVVM,… Tất cả đều có chung một mục đích là tổ chức, phân rã mã nguồn theo nhiều chức năng và nhiệm vụ khác nhau trong hệ thống.

Trong các hệ thống hướng đối tượng, UI, Database và các dạng mã khác thường được viết trực tiếp vào trong logic nghiệp vụ. Và theo chiều ngược lại, mã nghiệp vụ lâu lâu lại được nhúng vào trong UI, DB code. Không có sự phân cấp rõ ràng dẫn đến sự phức tạp trong tổ chức, quá nhiều phụ thuộc lẫn nhau giữa các mã nguồn. Sở dĩ điều này diễn ra là vì lập trình nó rất dễ và nhanh.. nhưng chỉ là lúc mới bắt đầu. Khi các đoạn mã liên quan đến nghiệp vụ được dàn trải ở khắp nơi, điều này sẽ trở nên rất phức tạp và rất khó để đọc hiểu được nghiệp vụ. Thay đổi trên giao diện người dùng cũng có thể làm thay đổi business logic. Để thay đổi business logic, chúng ta phải đi ngược lên các mã UI, cơ sở dữ liệu hoặc các phần tử của chương trình khác để xem những chỗ cần phải thay đổi theo. Điều này không cần nói cũng đủ hiểu nó gây ra khó khăn như thế nào.

Có 3 layers được chia ra:

User Interface (Presentation): là những chương trình chạy trên desktop / CLI hoặc các web page. Các chương trình client lúc này thường là các rich client (nơi luồng công việc và kiểm tra input đầu vào đặt ở client)

Business Logic (Domain): là nơi đặt các logic về nghiệp vụ chính của hệ thống, layer này sẽ tiếp nhận các request từ phía Client, xử lý và lưu trữ data thông qua Data source layer.

Data source: nhiệm vụ chính của layer này là thực thi các tác vụ lưu trữ dữ liệu và liên lạc với các applications khác (được request từ business logic layer).

1.1 Layered design with segmented layers

Ưu điểm:

  • Chúng ta chỉ cần hiểu những lớp bên dưới lớp chúng ta đang làm;
  • Mỗi lớp có thể được thay thế bởi một thể hiện tương đương (equivalent implementation), không ảnh hưởng đến các lớp khác;
  • Một lớp có thể được sử dụng bởi một số lớp cấp cao khác nhau.

Những bất lợi là:

  • Lớp không thể đóng gói (encapsulate) tất cả mọi thứ (một field được thêm vào UI, rất có thể cũng cần phải được thêm vào DB);
  • Các lớp bổ sung (extra) có thể gây ảnh hưởng đến hiệu suất, đặc biệt nếu ở các tier khác nhau.

Ứng dụng:

  • Kiến trúc xây dựng website (N-Tier)

Kiến trúc Component và Connector

Broker Pattern

Mẫu này được sử dụng để cấu trúc các hệ thống phân tán với các thành phần tách rời. Các thành phần này có thể tương tác với nhau bằng các yêu cầu dịch vụ từ xa. Broker chịu trách nhiệm điều phối tương tác giữa các thành phần.

Máy chủ sẽ đưa ra broker như là giao diện kết nối nhận request từ phía người dùng. Khi khách hàng yêu cầu một dịch vụ từ broker và broker sẽ chuyển hướng khách hàng đến một dịch vụ phù hợp đã đăng ký trước đó.

Different software architectural patterns and how to choose the ...

Nhược điểm

  • Broker bổ sung thêm 1 lớp broker ở giữa nên làm cho mô hình trở lên phức tạp và tăng latency giữa client và server.
  • Broker có thể là điểm đơn single point of failure và cũng có thể là đích tấn công của hacker.
  • Broker cũng tương đối khó

Ứng dụng:

  • Phần mềm trung gian như Apache ActiveMQ, Apache Kafka, RabbitMQ và JBoss Messaging

Mô hình MVC

Kiến trúc này, còn được gọi là mô hình MVC, phân chia một ứng dụng tương tác thành 3 phần: 

  • Model –  chứa chức năng và dữ liệu cốt lõi
  • View – hiển thị thông tin cho người dùng (có thể xác định nhiều hơn một chế độ xem)
  • Controller – xử lý yêu cầu đầu vào từ người dùng

Kiến trúc này được sử dụng để phân tách cách biểu diễn thông tin nội bộ khỏi cách thức trình bày thông tin và chấp nhận từ người dùng. Nó tách các thành phần và cho phép tái sử dụng code hiệu quả.

Ứng dụng: 

  • Kiến trúc cho các ứng dụng web bằng các ngôn ngữ lập trình chính.
  • Các web framework như Django và Rails.

Ưu điểm:

  • Nhẹ, tiết kiệm băng thông. Khi sử dụng, người dùng có thể sử dụng ứng dụng trên web cần tương tác gửi và nhận dữ liệu một cách liên tục. Do đó, việc giảm băng thông giúp cho website hoạt động tốt và ổn định hơn.
  • Đây là một mô hình với kết cấu tương đối đơn giản. Dù bạn không có quá nhiều chuyên môn cũng có thể sử dụng được.

Nhược điểm:

  • Sự phức tạp có thể không đáng giá cho các giao diện người dùng đơn giản
  • Mô hình MVC có thể không phù hợp với một số bộ công cụ giao diện người dùng

Kiến trúc đường ống và lọc (Pipe and filter pattern)

Pattern này được sử dụng để cấu trúc hóa các hệ thống sản xuất và xử lý luồng dữ liệu. Mỗi bước xử lý được đính kèm trong một thành phần bộ lọc (filter). Dữ liệu đã xử lý sẽ được truyền qua đường ống (pipe). Những ống này có thể được sử dụng để đồng bộ hoặc buffering.

Figure 4 - Implementing a pipeline using message queues

Ứng dụng:

  • Các tiến trình yêu cầu bởi ứng dụng có thể chia nhỏ ra thành các bước độc lập.
  • Hệ thống cần phân tán công đoạn xử lý trên nhiều máy chủ khác nhau

Nhược điểm

  • Mẫu ống và bộ lọc thường không phải là một lựa chọn tốt cho một hệ thống tương tác. Có số lượng lớn các bộ lọc độc lập có thể thêm số lượng đáng kể chi phí tính toán.
  • Kiến trúc này thường không phù hợp cho các tính toán thời gian dài

Kiến trúc Client – Server

Kiến trúc này bao gồm hai thành phần: một server và nhiều clients. Server sẽ cung cấp dịch vụ cho nhiều clients. Ngược lại, các client gửi request tới server để xử lý và trả các service tương ứng cho phía client đó. Song song đó, máy chủ vẫn luôn tiếp tục tiếp nhận requests từ clients.

Ứng dụng:

  • Các ứng dụng trực tuyến như email, chia sẻ tài liệu và ngân hàng.

Nhược điểm

  • Gây lên vấn đề bottle neck tại server
  • Server có thể là điểm single point

Kiến trúc Peer to Peer

Pattern này, các thành phần riêng lẻ được gọi là peer. Các peers này có thể hoạt động như một khách hàng, yêu cầu dịch vụ từ các peers khác và như một máy chủ, cung cấp dịch vụ cho các peers. Một peer có thể hoạt động như một khách hàng hoặc máy chủ hoặc cả hai, và có thể thay đổi vai trò của nó linh hoạt theo thời gian.

Sử dụng: 

  • Các mạng lưới chia sẻ file như Gnutella và G2)
  • Các giao thức đa phương tiện như P2PTV và PDTP.

Kiến trúc SOA

Kiến trúc hướng dịch vụ là một chiến dịch cho biết dự định xây dựng tất cả các tài sản phần mềm của công ty đó bằng cách sử dụng phương pháp luận lập trình hướng dịch vụ. Trong đó Dịch vụ là khúc dữ liệu phần mềm hoặc các cấu phần được cấu trúc để chúng có thể liên kết với các cấu phần phần mềm khác một cách dễ dàng.

Nhược điểm

  • Nền tảng kiến trúc này tương đối phức tạp để xây dựng
  • Không thể kiểm soát sự phát triển của các dịch vụ độc lập
  • Phát sinh các vấn đề liên quan đến hiệu năng xử lý tại tầng middware

Kiến trúc Publish/Suscriber

Trong hệ thống phân tán lớn, message broker là một thành phần vô cùng quan trọng. Lý do vì sao mình xin thứ lỗi không giải thích ở đây. Hiện nay, có 2 messaging model phổ biến là message queuing và pub/sub messaging.

Việc đưa message vào hàng đợi là một giải pháp hay khi ta muốn phân tán message cho nhiều người nhận giúp giảm tải cho các worker xử lý. Vd như RabbitMQ thay vì phải xử lý 1 tác vụ rất ngốn tài nguyên thì có thể chia nhỏ thành nhiều tác vụ nhỏ và phân tán.

Message queuing được thiết kế để thực hiện danh sách task một cách lần lượt. Khi một message đến, hàng đợi sẽ tiếp nhận. Nếu task trước đó đã thực thi xong, message đó sẽ bị xóa, message kế tiếp mới được gửi đi để xử lý task tương ứng. Vậy thì ở đây, với message queuing, nếu như một message bị lỗi gì đó, thì có thế các message sau sẽ không được xử lý theo tuần tự nữa. 

Pub/Sub messaging cũng làm nhiệm vụ giống như message queuing. Tuy nhiên, cơ chế của pub/sub có khác biệt:

  • Pub – Publish: producer sẽ đẩy data vào một chanel.
  • Sub – Subscribe: consumer đăng ký nhận dữ liệu từ một chanel. 

Cái này giống như bạn xem Youtube. Bạn subscribe một channel. Khi một producer làm một video đẩy lên Youtube. Bạn sẽ nhận dữ liệu, tức xem video đó tại channel mà bạn đã subscribe. Khi bạn bè của bạn cũng subscribe channel đó, thì khi producer đẩy video lên, bạn và bạn bè của bạn cùng nhận được video để xem. Và tất nhiên, bạn có thể đăng ký nhiều channel.

Và tất nhiên mỗi messaging model có một ưu điểm riêng và tùy vào bài toán mà sử dụng chúng.

Message Queue| Pub/Sub |
+————–+—————+
| RabitMQ | Kafka |
+————–+—————+
| ActiveMQ | Kinesis |
+————–+—————+
| SQS | RocketMQ |
+————–+—————+
| ZeroMQ | |
+————–+—————+
| MSMQ | |
+————–+—————+
| IronMQ | |
+————–+————–

  • Đối với loại “message queue”: là những loại message queue truyền thống, thích hợp làm hệ thống trao đổi message giữa các service. Việc đảm bảo mỗi consumer đều nhận được message và duy nhất một lần là quan trọng nhất.
  • Đối với loại “Pub/Sub”, có cách lưu trữ message cũng như truyền tải message đến consumer hoàn toán khác với hệ thống message queue truyền thống. Việc đảm bảo mỗi consumer đều phải nhận được message và duy nhất một lần không phải là ưu tiên số một, mà thay vào đó là khả năng lưu trữ message vả tốc độ truyền tải message. Khi có message mới, consumer sẽ lựa chọn số lượng message mà mình muốn lấy, chính vì thế mà cùng một message consumer có thể nhận đi nhận lại nhiều lần. Những hệ thống sử dụng message queue loại này thường là hệ thống Event Sourcing, hoặc hệ thống đồng bộ dữ liệu từ những database khác nhau như Debezium.

Ứng dụng:

  • MQTT

Tham khảo

https://docs.microsoft.com/en-us/azure/architecture/patterns/

https://medium.com/@nethmihettiarachchi484/common-software-architectural-patterns-in-a-nutshell-7df312d3989c

Các Design Pattern cần biết

Kiến trúc phân lớp

Leave a Reply

Your email address will not be published. Required fields are marked *