Loading...

Định hướng thiết kế kiến trúc phần mềm/Triết lý thiết kế kiến trúc phần mềm

1. Mục đích

Bạn bắt đầu hành trình khởi nghiệp bằng việc xây dựng Web, WebApp, MobileApp, App, … (có thể gọi tắt là phần mềm) của riêng mình?

Bạn đang là đầu tàu cho một dự án phần mềm của công ty?

Ý tưởng về phần mềm mà bạn đã có nhưng chưa thể xác định được kiến trúc, cách thiết kế như thế nào là phù hợp?

Mục tiêu của chúng tôi là cung cấp cho bạn sự hiểu biết vững chắc về thiết kế và lên một kiến ​​trúc cho phần mềm, các khái niệm liên quan và cách chọn kiến ​​trúc/ công nghệ phù hợp khi thiết kế phần mềm của mình. Khi đọc hết bài viết này, bạn sẽ có phương hướng khi thiết kế một phần mềm từ tổng quan ban đầu.

2. Lợi ích

Thông qua bài viết này, bạn sẽ xác định được phương hướng xây dựng kiến trúc bằng cách tìm câu trả lời với phương pháp 5W-1H: What – When – Where – Why – Who – How?

Cốt lõi vấn đề là những ý chính sau:

  • Kiến trúc logic phần mềm là gì?
  • Tại sao kiến trúc phần mềm lại quan trọng?
  • Điểm khác biệt giữa kiến trúc và thiết kế phần mềm là gì?
  • Khuôn mẫu phát triển phần mềm ứng dụng là gì?
  • Làm sao để xác định số tầng kiến trúc cho ứng dụng?
  • Khả năng mở rộng theo chiều ngang (horizontal – scale-out) hay chiều dọc (vertical – scale-up)?
  • Kiến trúc thuần túy nguyên khối (monolith) hay kiến trúc theo hướng dịch vụ chia nhỏ(microservices)?
  • CSDL quan hệ (SQL) hay CSDL phi quan hệ (NoSQL)?
  • Lựa chọn đúng công nghệ sử dụng
  • … và còn nhiều hơn thế nữa

3. Phân tích

3.1 Kiến trúc logic phần mềm là gì?

Kiến trúc logic phần mềm của một hệ thống mô tả các thành phần chính của nó, các mối quan hệ giữa chúng và cách chúng tương tác với nhau.

Về bản chất, nó như một bản thiết kế logic phần mềm, với những khía cạnh trừu tượng nhằm quản lý sự phức tạp của hệ thống, mô tả cách thức giao tiếp và phối hợp giữa các thành phần.

Mục đích chính của việc xác định kiến trúc logic của phần mềm:

  • Kiến trúc logic giúp xác định giải pháp để đáp ứng tất cả các yêu cầu kỹ thuật và vận hành, với mục tiêu chung là tối ưu hóa hiệu suất và bảo mật.
  • Thiết kế kiến ​​trúc tập trung đến phần giao của nhu cầu tổ chức và nhu cầu của nhóm phát triển. Mỗi quyết định có thể có một tác động đáng kể đến chất lượng, khả năng bảo trì, hiệu suất, v.v.

3.2 Tại sao kiến trúc logic phần mềm lại quan trọng?

Xây dựng một tòa nhà hoặc làm một chiếc bánh – để có thể thành công với bất kỳ thứ gì, ta cần phải có cơ sở căn bản chắc chắn – đó là quy luật tự nhiên, xây dựng một hệ thống ứng dụng Web cũng không là ngoại lệ.

Kiến trúc là nền tảng cơ sở, nó cần được đánh giá, thiết kế kỹ lưỡng, và tránh những thay đổi thiết kế lớn và tái cấu trúc mã nguồn.

Các quyết định vội vàng được đưa ra trong các giai đoạn thiết kế ban đầu có thể gây ra bế tắc ở bất kỳ giai đoạn nào trong quá trình phát triển. Vì vậy, trước khi chúng ta tập trung phát triển mã nguồn ứng dụng, chúng ta phải làm cho đúng kiến ​​trúc cơ bản.

Phát triển hệ thống ứng dụng là một quá trình lặp đi lặp lại và tăng tiến – không phải lúc nào cũng làm đúng mọi thứ ngay từ đầu, nhưng quan trọng là phải biết lắng nghe và điều chỉnh.

3.3 Sự khác biệt giữa kiến trúc phần mềm và thiết kế phần mềm

Thường có nhiều sự nhầm lẫn giữa 02 khái niệm này, cần xác định rõ để tránh mất phương hướng.

Kiến trúc phần mềm được sử dụng để xác định bộ khung và các thành phần logic cấp cao (high-level) của một hệ thống và cách chúng sẽ làm việc cùng nhau.

Việc lựa chọn kiến ​​trúc sẽ xác định cách chúng ta đối phó với hiệu suất, khả năng chịu lỗi, khả năng mở rộng và độ tin cậy cho hệ thống ứng dụng.

Thiết kế phần mềm có trách nhiệm xây dựng kiến trúc ở mức mã nguồn (code-level) – Môđun này sẽ làm gì? Phạm vi tính năng? Chức năng? Mục đích? …

3.4 Khuôn mẫu phát triển ứng dụng

3.4.1 Máy khách – máy chủ (Client – Server)

Kiến trúc hoạt động trên một mô hình đáp ứng yêu cầu. Máy khách gửi yêu cầu đến máy chủ và máy chủ trả lời nó (server side/ client side).

3.4.2 Mạng ngang hàng (Peer-to-Peer)

Mạng ngang hàng là mạng mà các thành phần tham gia có thể giao tiếp với nhau mà không cần máy chủ trung tâm.

Việc không có máy chủ trung tâm sẽ loại bỏ điểm lỗi duy nhất của hệ thống.

Tất cả các thành phần tham gia có quyền và tính năng như nhau, vì vậy khi một số máy tính/ thành phần mất kết nối hoặc hỏng hóc, mạng và hệ thống vẫn hoạt động bình thường.

3.4.3 Mô hình MVC (Model – View – Controller)

Kiến trúc MVC là một mẫu kiến ​​trúc phần mềm trong đó logic ứng dụng được chia thành ba thành phần dựa trên cơ sở chức năng.

Các thành phần bao gồm:

  • Mô hình – thể hiện cách dữ liệu được lưu trữ trong cơ sở dữ liệu.
  • Cách hiển thị – các thành phần hiển thị cho người dùng, chẳng hạn như đầu ra dữ liệu hoặc giao diện người dùng.
  • Bộ điều khiển – thành phần logic hoạt động như lõi xử lý giữa mô hình và cách hiển thị.

3.4.4 Khuôn mẫu dịch vụ nhỏ (Microservices)

Trong kiến ​​trúc microservice, các tính năng/ nhiệm vụ khác nhau được chia thành các mô-đun/ cơ sở mã nguồn tương ứng riêng biệt, hoạt động cùng với nhau để tạo thành một dịch vụ lớn.

Kiến trúc này tạo điều kiện cho việc bảo trì ứng dụng dễ dàng và đơn giản hơn, phát triển tính năng, thử nghiệm và triển khai so với kiến ​​trúc nguyên khối.

3.4.5 Khuôn mẫu hướng sự kiện (Event-driven)

Kiến trúc hướng sự kiện – còn được gọi là kiến ​​trúc phản ứng sự kiện – khá phổ biến trong sự phát triển ứng dụng web hiện đại.

Nó có khả năng xử lý một số lượng lớn các kết nối đồng thời với mức tiêu thụ tài nguyên tối thiểu. Các ứng dụng hiện đại cần một mô hình không đồng bộ hoàn toàn để mở rộng quy mô. Kiến trúc này cung cấp khả năng xử lý sự kiện đáng tin cậy trong một môi trường phân tán.

3.4.6 Khuôn mẫu phân tầng (Layered)

Khuôn mẫu này có thể được sử dụng để phân tách cấu trúc ứng dụng thành nhiều nhóm, mỗi nhóm đều ở một mức độ trừu tượng cụ thể.

Mỗi lớp cung cấp dịch vụ cho lớp cao hơn tiếp theo.

Các nhóm/ tầng trừu tượng thường thấy:

  • Tầng trình bày (Presentation layer)
  • Tầng ứng dụng (Application layer)
  • Tầng logic kinh doanh (Business logic layer)
  • Tầng kết nối dữ liệu (Data access layer)

3.5 Xác định số tầng kiến trúc cho ứng dụng

3.5.1 Ứng dụng 01 tầng

Thường là loại ứng dụng Portable, được cài thẳng trên máy người dùng cuối.

Ví dụ: các phần mềm nghe nhạc, giải trí ngoại tuyến…

Ưu điểm:

  • Không có độ trễ về mạng
  • Dữ liệu có sẵn và nhanh chóng
  • Dữ liệu không cần truyền qua mạng, đảm bảo an toàn dữ liệu

Khuyết điểm:

  • Ít kiểm soát ứng dụng, khó phát triển/ thay đổi mã nguồn sau khi triển khai.
  • Phải kiểm tra kỹ lưỡng, đảm bảo tối thiểu lỗi trước khi triển khai
  • Ứng dụng dễ bị truy vết ngược.

3.5.2 Ứng dụng 02 tầng

Thường là loại ứng dụng được thiết kế dựa trên nhu cầu, được cài thẳng trên máy chủ của tổ chức/ người dùng cuối.

Ví dụ: các phần mềm đặc thù, nghiệp vụ…

Ưu điểm:

  • Độ trễ mạng thấp, vì thường là hệ thống nguyên khối
  • Máy chủ cơ sở dữ liệu và logic kinh doanh nằm chung, cung cấp hiệu năng cao khi sử dụng ở điều kiện vừa phải

Khuyết điểm:

  • Vì người dùng cuối nắm giữ hầu hết logic ứng dụng, nên các vấn đề phát sinh trong việc kiểm soát phiên bản phần mềm và phân phối lại các phiên bản mới rất khó thực hiện được.
  • Thiếu khả năng mở rộng vì chỉ hỗ trợ một số lượng người dùng hạn chế. Khi nhiều yêu cầu của máy khách tăng lên, hiệu suất ứng dụng có thể bị giảm.
  • Vì logic ứng dụng liền một thể với logic kinh doanh của người dùng cuối, nên rất tái sử dụng logic.

3.5.3 Ứng dụng 03 tầng

Thường là loại ứng dụng phục vụ cho một tổ chức/ doanh nghiệp với logic hoạt động riêng, có nhu cầu phân tách và mở rộng ở một mức độ xác định.

Ví dụ: Ứng dụng kinh doanh, thống kê tài sản doanh nghiệp bán lẻ trực tuyến…

Ưu điểm:

  • Nhờ việc triển khai phân tán các máy chủ ứng dụng, khả năng mở rộng của hệ thống được tăng cường.
  • Có thể thông suốt hoạt động với nhiều cơ chế đảm bảo dữ liệu

Khuyết điểm:

  • Thông thường, việc thiết kế loại ứng dụng này đòi hỏi sự kết hợp đồng bộ giữa các tầng logic.
  • Cần sự thống nhất khi xác định xây dựng ứng dụng ba tầng khi các phần giao được tăng lên (máy khách đến đến máy chủ, máy chủ này đến máy chủ khác).

3.5.4 Ứng dụng N tầng

Là các loại ứng dụng phục vụ hướng đến cộng đồng lớn/ thị trường quốc tế.

Ví dụ: Ứng dụng xem phim trực tuyến, ứng dụng mạng xã hội…

Ưu điểm:

  • Tương tự ưu điểm của nhóm ứng dụng 03 tầng, với khả năng mở rộng, khả năng đảm bảo dữ liệu cao hơn.

Khuyết điểm:

  • Do sự phân chia thành nhiều thành phần nhỏ, cấu trúc hệ thống trở nên phức tạp và yêu cầu khả năng kỹ thuật cao để vận hành/ duy trì.

 

3.5.5 Lựa chọn nào là phù hợp?

Đối với kiến trúc ứng dụng 01 tầng, chỉ nên sử dụng khi ứng dụng không phụ thuộc vào mạng, và hướng đến sự gọn nhẹ cho người dùng cuối.

Kiến trúc ứng dụng 02 tầng phù hợp cho các hệ thống ứng dụng phục vụ một mục đích nghiệp vụ cụ thể, với độ trễ xử lý thấp cùng khả năng quản lý dữ liệu cục bộ.

Nên sử dụng kiến trúc ứng dụng 03 tầng khi cần kiểm soát logic nghiệp vụ của hệ thống ứng dụng cỡ vừa và lớn. Nó cung cấp khả năng bảo mật và khả năng kiểm soát dữ liệu trong hệ thống cho từng tầng kiến trúc hoạt động.

Ứng dụng N tầng chỉ nên được sử dụng khi đã xác định chiến lược phát triển sản phẩm và đội ngũ kỹ thuật vững vàng, cụ thể là khả năng mở rộng cực cao với khả năng xử lý một lượng lớn dữ liệu liên tục của loại kiến trúc này.

3.6 Mở rộng theo chiều ngang (Horizontal) hay chiều dọc (Vertical)?

Nếu như hệ thống ứng dụng của bạn chỉ là một dạng công cụ/ tiện ích được thiết kế để đáp ứng lưu lượng thấp dữ liệu, có thể là một ứng dụng quản lý nội bộ, thì hiển nhiên nó không cần phải nằm trên một môi trường phân tán.

Những trường hợp như vậy, một máy chủ đơn giản là quá đủ để xử lý luồng dữ liệu và phục vụ người dùng, vì ta biết lưu lượng xử lý sẽ không tăng đột ngột.

  • Mở rộng theo chiều dọc (Vertical) bằng cách nâng cấp thêm tài nguyên.

Nhưng nếu ứng dụng của bạn là một ứng dụng phục vụ cộng đồng/ xã hội như mạng xã hội, một ứng dụng năng động, hoặc gì đó giống vậy, lưu lượng dữ liệu cũng như nhu cầu xử lý đột ngột tăng mạnh trong tương lai gần, thì chắc chắn sẽ phải cần đến khả năng mở rộng theo chiều ngang (Horizontal) và tính sẵn sàng cao của nó.

  • Mở rộng theo chiều ngang (Horizontal) bằng cách thêm thực thể xử lý (Instance)

3.7 Kiến trúc thuần tùy nguyên khối (Monolith) hay kiến trúc dịch vụ nhỏ (Microservices)

Khi nào thì sử dụng kiến trúc nguyên khối?

Các ứng dụng nguyên khối phù hợp nhất khi giải quyết các yêu cầu logic đơn giản và ứng dụng dự kiến ​​sẽ xử lý một lượng lưu lượng dữ liệu xác định.

Ví dụ: ứng dụng tính thuế nội bộ cho một tổ chức hoặc một công cụ công khai mở tương tự.

Đây là những trường hợp sử dụng mà doanh nghiệp chắc chắn rằng sẽ không có tăng trưởng theo cấp số nhân trong lượng người dùng và lưu lượng truy cập theo thời gian.

Khi nào thì sử dụng kiến trúc dịch vụ nhỏ?

Kiến trúc dịch vụ nhỏ (Microservices) phù hợp nhất cho các trường hợp sử dụng phức tạp và cho các ứng dụng dự kiến ​​lưu lượng truy cập sẽ tăng theo cấp số nhân trong tương lai, giống như một ứng dụng mạng xã hội.

Một ứng dụng mạng xã hội thông thường có nhiều thành phần khác nhau, như nhắn tin, trò chuyện thời gian thực, phát video trực tiếp, tải lên hình ảnh, thích và chia sẻ các tính năng, v.v. Trong trường hợp này, hãy phát triển từng thành phần riêng biệt, giữ nguyên nhiệm vụ và tách biệt các nguyên tắc xử lý.

Mỗi tính năng, mỗi đội ngũ, MỘT cơ sở mã nguồn sẽ dễ dàng trở thành một mớ hỗn độn, vì khả năng quản lý, phát triển thành công đã bị phụ thuộc.

Tuy nhiên cũng có một số trường hợp một sản phẩm bắt đầu với kiến trúc nguyên khối thuần túy, và được mở rộng, phát triển thành kiến trúc dịch vụ nhỏ sau một khoảng thời gian phát triển.

3.8 CSDL quan hệ (SQL) hay CSDL phi quan hệ (NoSQL)?

3.8.1 Khi nào nên chọn cơ sở dữ liệu quan hệ (SQL)?

Nếu bạn đang viết một ứng dụng giao dịch chứng khoán, ngân hàng hoặc ứng dụng dựa trên tài chính hoặc bạn cần lưu trữ nhiều mối quan hệ, thì bạn nên chọn cơ sở dữ liệu quan hệ.

Giao dịch và tính thống nhất dữ liệu:

Nếu bạn viết phần mềm có liên quan đến tiền hoặc số, thực hiện giao dịch hoặc phải tuân thủ nguyên tắc ACID (atomicity, consistency, isolation, durability) – tính nhất quán dữ liệu là vô cùng quan trọng.

Cơ sở dữ liệu quan hệ mặc nhiên sẽ là lựa chọn sáng suốt nhất khi nói đến các giao dịch và tính nhất quán dữ liệu – chúng tuân thủ quy tắc ACID, thứ đã có từ rất lâu, được thử nghiệm và sử dụng bởi những ngân hàng hàng đầu thế giới.

Lưu trữ các mối quan hệ dữ liệu:

Nếu dữ liệu của bạn có nhiều mối quan hệ ràng buộc quan trọng với nhau như dữ liệu dân số ở một thành phố cụ thể? Số tiền này thuộc về ai? V.v. Không có gì tốt hơn một cơ sở dữ liệu quan hệ để lưu trữ loại dữ liệu này. Cơ sở dữ liệu quan hệ được xây dựng để lưu trữ các mối quan hệ ràng buộc của dữ liệu.

Một số hệ quản trị cơ sở dữ liệu quan hệ nổi tiếng:

  • MySQL
  • Microsoft SQL Server
  • PostgreSQL
  • MariaDB

3.8.2 Khi nào nên chọn cơ sở dữ liệu phi quan hệ (NoSQL)?

Bản chất của cơ sở dữ liệu NoSQL là sự phát triển của việc đọc ghi dữ liệu trên File, chỉ khác ở chỗ ngày đó chưa có công cụ xịn như hiện tại.

Xử lý một số lượng lớn các hoạt động đọc-ghi

Hãy hướng lựa chọn về phía cơ sở dữ liệu NoSQL khi bạn cần mở rộng nhanh.

Ví dụ: khi có một số lượng lớn các thao tác đọc-ghi trên trang web của bạn và khi xử lý một lượng lớn dữ liệu, cơ sở dữ liệu NoSQL phù hợp nhất trong các tình huống này. Vì chúng có khả năng thêm các thực thể xử lý một cách nhanh chóng, chúng có thể xử lý lưu lượng đồng thời nhiều hơn và lượng dữ liệu lớn với độ trễ tối thiểu.

Chạy các hệ thống phân tích dữ liệu

Cơ sở dữ liệu NoSQL cũng phù hợp nhất cho các trường hợp sử dụng phân tích dữ liệu, khi đó chúng ta phải đối phó với một lượng lớn dữ liệu xử lý liên tục.

Một số hệ quản trị cơ sở dữ liệu phi quan hệ nổi tiếng:

  • MongoDB
  • Redis
  • Cassandra
  • HBASE

3.9 Chọn công nghệ phù hợp cho công việc

Việc lựa chọn có một phần phụ thuộc vào nhu cầu hiện hữu trước mắt.

Tương tác dữ liệu thời gian thực

Nếu bạn đang xây dựng một ứng dụng cần tương tác với máy chủ Backend trong thời gian thực, chẳng hạn như ứng dụng nhắn tin hoặc ứng dụng phát trực tuyến video âm thanh như Spotify, Netflix, v.v… và một kết nối liên tục giữa máy khách và máy chủ cùng nhu cầu tương thích công nghệ ở hệ thống lõi.

  • Hãy lựa chọn NodeJS hoặc một Framework Python nổi tiếng như Tornado

Ứng dụng Web ngang hàng (Peer-to-Peer)

Nếu bạn có ý định xây dựng một ứng dụng web ngang hàng, một công cụ tìm kiếm phân tán P2P hoặc dịch vụ nào đó tương tự thì bạn sẽ muốn xem xét các giao thức JavaScript như DAT và IPFS.

  • Hãy xem xét FreedomJS, một Framework để xây dựng các ứng dụng web P2P hoạt động trong các trình duyệt web hiện đại.

Ứng dụng dựa trên CRUD

Nếu bạn có các trường hợp sử dụng đơn giản như ứng dụng dựa trên triết lý CRUD thông thường (Create – Read – Update – Delete), một số công nghệ bạn có thể sử dụng là: Spring MVC, Python Django, Ruby on Rails, PHP Laravel và ASP .NET MVC.

Ứng dụng đơn giản, quy mô nhỏ

Nếu bạn có ý định viết một ứng dụng không liên quan đến sự phức tạp, như blog, một hình thức trực tuyến đơn giản hoặc các ứng dụng đơn giản tích hợp với phương tiện truyền thông xã hội và trong phạm vi của cổng thông tin, quản lý nội dung, hãy sử dụng PHP.

Bạn cũng có thể xem xét các Framework Web khác như Spring boot, Ruby on Rails, giúp cắt giảm tính dài dòng, cấu hình, thời gian phát triển bằng cách tạo ra & tạo điều kiện cho sự phát triển nhanh chóng. Nhưng PHP sẽ có chi phí ít hơn nhiều so với các công nghệ khác. Đó là lý tưởng cho các trường hợp sử dụng rất đơn giản.

Các ứng dụng chuyên sâu dành cho CPU và bộ nhớ

Bạn có cần chạy các tác vụ tính toán nặng, tốn bộ nhớ, CPU ở Backend không? Bạn có cần xử lý dữ liệu lớn, xử lý song song hoặc chạy theo dõi và phân tích trên một lượng lớn dữ liệu không?

Các Framework Web và các ngôn ngữ script thông thường thường không được nhắm đến cho mục đích này. Công nghệ được sử dụng trong công nghiệp để viết các hệ thống phân tán, có khả năng xử lý và mở rộng lớn là C ++.

C++ có các tính năng hỗ trợ thao tác bộ nhớ cấp thấp, cung cấp nhiều quyền kiểm soát bộ nhớ hơn cho các nhà phát triển khi viết các hệ thống phân tán.

Ngoài ra còn có Rust – một ngôn ngữ lập trình tương tự như C ++. Nó được xây dựng để đảm bảo hiệu suất cao và đồng thời an toàn . Nó đã được phổ biến gần đây giữa các nhà phát triển. Java, Scala và Erlang cũng là những lựa chọn tốt. Hầu hết các hệ thống doanh nghiệp quy mô lớn được viết bằng Java.

Bên cạnh đó còn có Go – ngôn ngữ lập trình của Google để viết ứng dụng cho các máy chủ đa lõi và xử lý một lượng lớn dữ liệu.

4. Lời kết và sự khởi đầu

Chúng ta đã đi qua rất nhiều thông tin trong bài viết này, nhưng tất cả chỉ là bề nổi Logic của chủ đề này.

Bạn có thể tìm hiểu về các phong cách kiến trúc khác nhau như máy khách-máy chủ, kiến trúc phi tập trung ngang hàng, microservice, các nguyên tắc cơ bản của luồng dữ liệu trong một ứng dụng web, các khái niệm như khả năng mở rộng, tính sẵn sàng cao và nhiều hơn nữa sau bài viết này.

Ngoài ra, bạn sẽ trải qua các kỹ thuật thiết kế kiến trúc và xây dựng các tầng công nghệ để triển khai trường hợp sử dụng của riêng bạn. Đồng thời qua quá trình sử dụng lâu dài, bạn – với những kinh nghiệm với sản phẩm của chính mình – sẽ hiểu được sự đánh đổi khi lựa chọn công nghệ.

Cuối cùng, xin cảm ơn đã đọc bài viết và chúc may mắn khi bắt đầu bước trên con đường này.

Tham khảo:

https://medium.com/better-programming/how-to-design-a-web-application-software-architecture-101-df568b88da76
https://www.n-ix.com/microservices-vs-monolith-which-architecture-best-choice-your-business/
https://www.guru99.com/sql-vs-nosql.html
https://stackify.com/n-tier-architecture/
https://medium.com/@abhinavkorpal/scaling-horizontally-and-vertically-for-databases-a2aef778610c
https://medium.com/educative/the-7-most-important-software-design-patterns-d60e546afb0e
HONEYNET

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *