1.1 Kiến trúc ứng dụng

Khóa học này được thiết kế cho người mới bắt đầu, bởi vì bạn sẽ không thiết kế kiến ​​trúc của một ứng dụng nghiêm túc trong một thời gian dài. Nhưng đừng lo lắng, kiến ​​trúc tốt là ngoại lệ chứ không phải là quy tắc. Rất khó để chọn đúng kiến ​​trúc ứng dụng trước khi xây dựng ứng dụng.

Ví dụ về các kiến ​​trúc phổ biến cho các ứng dụng máy chủ lớn:

  • Kiến trúc phân lớp (Layered Architecture).
  • Kiến trúc tầng.
  • Kiến trúc hướng dịch vụ (SOA).
  • Kiến trúc vi dịch vụ (Microservice Architecture).

Mỗi người trong số họ có ưu và nhược điểm của nó. Nhưng nghiên cứu chúng sẽ không cung cấp cho bạn bất cứ điều gì. Kiến trúc là câu trả lời cho câu hỏi “làm thế nào để tổ chức sự tương tác của hàng nghìn đối tượng bên trong hệ thống” . Và cho đến khi bạn trải nghiệm toàn bộ sự phức tạp của vấn đề, bạn sẽ không thể hiểu được toàn bộ tính linh hoạt của giải pháp.

Tất cả các ứng dụng sử dụng một số loại kiến ​​trúc, hoặc ít nhất là giả vờ như vậy. Do đó, kiến ​​thức về các cách tiếp cận phổ biến đối với thiết kế ứng dụng sẽ cho phép bạn hiểu nhanh hơn và hiểu rõ hơn về cách thức hoạt động của ứng dụng. Và điều đó có nghĩa là thực hiện các thay đổi chính xác ở nơi bạn cần.

"Thực hiện các thay đổi khi cần thiết" nghĩa là gì? Có những nơi mà bạn không cần phải thay đổi? Chính xác.

Để cụ thể hơn, giả sử bạn đang làm việc trên một dự án phụ trợ trung bình . Nó đã được viết trong 5 năm bởi một nhóm gồm 20 người. Dự án mất 100 năm công và chứa khoảng 100 nghìn dòng mã. Tổng cộng, nó bao gồm hai nghìn lớp, được chia thành 10 mô-đun có kích cỡ khác nhau.

Và thêm một thực tế phũ phàng. Logic của một số nhiệm vụ được trải rộng trên một số mô-đun. Ngoài ra, logic nghiệp vụ có thể ở giao diện người dùng (được viết bằng JavaScript) và/hoặc được viết dưới dạng thủ tục được lưu trữ trực tiếp trong cơ sở dữ liệu. Bạn vẫn chắc chắn rằng bạn có thể xác định ngay nơi chính xác để thực hiện các thay đổi ?

Đây không phải là cơn ác mộng tôi bịa ra để dọa bạn. Đây là một dự án điển hình. Nó xảy ra thậm chí còn tồi tệ hơn. Tại sao chuyện này đang xảy ra? Có thể có nhiều lý do, nhưng hầu như luôn có những lý do sau:

  • Rất nhiều người làm việc trong dự án - mỗi người trong số họ nhìn nhận nó hơi khác nhau.
  • Trong 5 năm, 10 người trong dự án đã thay đổi, những người mới đến không hiểu nhiều.
  • Tạo ra phần mềm là tạo ra những thay đổi liên tục làm thay đổi mọi thứ.
  • Năm năm trước, khi chúng tôi quyết định về kiến ​​trúc, ý tưởng của dự án có phần khác biệt.

Nhưng điều chính là bất kể kiến ​​​​trúc của dự án là gì, tất cả các lập trình viên làm việc trên nó đều có cùng hiểu biết về cách thức hoạt động của dự án này. Hãy bắt đầu với khái niệm đơn giản nhất - kiến ​​trúc client-server.

1.2 Khái niệm tương tác client-server

Bây giờ chúng ta sẽ hiểu khái niệm làm nền tảng cho kiến ​​trúc máy khách-máy chủ và sẽ cho phép bạn hiểu rõ hơn về cách tổ chức sự tương tác của hàng triệu chương trình trên Internet.

Như tên ngụ ý, khái niệm này liên quan đến hai bên: máy kháchmáy chủ . Mọi thứ giống như trong cuộc sống ở đây: khách hàng là khách hàng của dịch vụ này hoặc dịch vụ kia và máy chủ là nhà cung cấp dịch vụ. Máy khách và máy chủ là các chương trình vật lý , ví dụ một máy khách điển hình là một trình duyệt .

Các ví dụ sau đây có thể được đưa ra như một máy chủ:

  • Các máy chủ web như Tomcat.
  • Các máy chủ cơ sở dữ liệu như MySQL.
  • Các cổng thanh toán như Stripe.

Máy khách và máy chủ thường giao tiếp qua Internet (mặc dù chúng có thể hoạt động trong cùng một mạng cục bộ và nói chung trong bất kỳ loại mạng nào khác). Giao tiếp diễn ra trên các giao thức tiêu chuẩn như HTTP, FTP hoặc các giao thức cấp thấp hơn như TCP hoặc UDP.

Giao thức thường được chọn theo loại dịch vụ mà máy chủ cung cấp. Ví dụ: nếu đó là cuộc gọi video, thì UDP thường được sử dụng.

Bạn có nhớ Tomcat và các servlet của nó hoạt động như thế nào không? Máy chủ nhận được một thông báo HTTP, giải nén nó, trích xuất tất cả thông tin cần thiết từ đó và chuyển nó đến servlet để xử lý. Sau đó, kết quả xử lý được đóng gói lại thành phản hồi HTTP và được gửi tới máy khách.

Đây là tương tác máy khách-máy chủ điển hình. Trình duyệt là máy khách web và Tomcat là máy chủ web. Tomcat thậm chí còn được gọi là máy chủ web.

Nhưng nếu bạn nghĩ về nó, điều quan trọng không phải là cái tên, mà là bản chất - sự phân bổ vai trò giữa các chương trình. Tập lệnh JS của bạn đang chạy trong trang HTML cũng có thể được gọi là máy khách và servlet của bạn là máy chủ . Rốt cuộc, chúng hoạt động theo cặp trong khuôn khổ của khái niệm máy khách-máy chủ .

1.3 Một sắc thái quan trọng

Cũng cần lưu ý rằng tương tác máy khách-máy chủ dựa trên nguyên tắc rằng tương tác đó được khởi tạo bởi máy khách : máy chủ chỉ trả lời máy khách và báo cáo liệu nó có thể cung cấp dịch vụ cho máy khách hay không và nếu có thì với điều kiện nào. .

Không quan trọng vị trí của máy khách và máy chủ ở đâu. Phần mềm máy khách và phần mềm máy chủ thường được cài đặt trên các máy khác nhau, nhưng chúng cũng có thể chạy trên cùng một máy tính.

Khái niệm này được phát triển như một bước đầu tiên hướng tới việc đơn giản hóa một hệ thống phức tạp. Cô ấy có những điểm mạnh:

  • Đơn giản hóa logic : máy chủ không biết gì về máy khách và cách nó sẽ sử dụng dữ liệu của nó trong tương lai.
  • Có thể có các máy khách yếu : tất cả các tác vụ sử dụng nhiều tài nguyên có thể được chuyển giao cho máy chủ.
  • Phát triển độc lập mã máy khách và mã máy chủ.
  • Rất nhiều ứng dụng khách khác nhau, chẳng hạn như Tomcat và các trình duyệt khác nhau.

Phiên bản cơ bản nhất của sự tương tác giữa máy khách và máy chủ được hiển thị trong hình:

máy khách-máy chủ

Điều quan trọng cần lưu ý hai chi tiết ở đây. Đầu tiên, hình ảnh cho thấy nhiều khách hàng có thể truy cập vào một máy chủ. Thứ hai, họ có thể truy cập nó cùng một lúc. Đây cũng là một phần quan trọng của máy chủ.

Một khách hàng thường tương tác với một người dùng, do đó, thậm chí không cần ủy quyền ở đó. Tuy nhiên, máy chủ xử lý các yêu cầu từ hàng nghìn máy khách và khi phát triển mã cho nó, bạn cần có khả năng phân biệt giữa ủy quyền và xác thực.

Điều quan trọng nữa là máy chủ xử lý song song hàng nghìn yêu cầu. Và điều này có nghĩa là khi phát triển mã phụ trợ, bạn sẽ phải liên tục nghĩ về nhiệm vụ truy cập đồng thời vào tài nguyên. Ngoài ra, mã máy chủ có xác suất rất cao về tình trạng chủng tộc (cuộc đua luồng), bế tắc (chặn luồng lẫn nhau).

Vòng đời của các đối tượng quan trọng phải được theo dõi:

Bạn không thể bắt đầu một chủ đề mới trên máy chủ thông qua new Thread().start(). Thay vào đó, bạn cần có một ThreadPool sẽ chia sẻ giữa tất cả các luồng dịch vụ.

Ngoài ra, bạn không thể chỉ bắt đầu một tác vụ không đồng bộ vì chúng cũng được thực thi trong các luồng riêng biệt. Khi tạo một tác vụ như vậy, bạn phải luôn biết nhóm luồng nào đang thực thi nó và điều gì sẽ xảy ra nếu nhóm đó bị tràn.

Tất cả công việc với tệp và thư mục phải được thực hiện thông qua tài nguyên dùng thử. Nếu trong một ứng dụng bình thường, bạn quên đóng một luồng hoặc một tệp, đó có phải là vấn đề không? Nó sẽ tự đóng lại khi bạn thoát khỏi chương trình. Nhưng nếu bạn quên đóng một tệp trên máy chủ ở đâu đó trong mã và máy chủ của bạn đã chạy trong nhiều tháng ... Chẳng bao lâu nữa, hàng nghìn tệp không được đóng như vậy sẽ tích tụ và HĐH sẽ ngừng mở tệp mới để đọc (làm việc với tệp được điều khiển bởi hệ điều hành). Teamlead sẽ không xoa đầu bạn đâu...

1.4 Kiến trúc client-server

một điểm quan trọng khác. Kiến trúc máy khách-máy chủ chỉ xác định các nguyên tắc chung của sự tương tác giữa các máy tính , các chi tiết của sự tương tác được xác định bởi các giao thức khác nhau.

Khái niệm này (máy khách-máy chủ) cho chúng ta biết rằng chúng ta cần chia các máy trên mạng thành máy khách luôn cần thứ gì đó và máy chủ cung cấp thứ chúng cần. Trong trường hợp này, máy khách luôn bắt đầu tương tác và các quy tắc mà tương tác xảy ra được mô tả bởi giao thức.

Có hai loại kiến ​​trúc tương tác máy khách-máy chủ: loại thứ nhất được gọi là kiến ​​trúc máy khách-máy chủ hai tầng, loại thứ hai là kiến ​​trúc máy khách-máy chủ nhiều tầng (đôi khi được gọi là kiến ​​trúc ba tầng hoặc kiến ​​trúc ba tầng, nhưng đây là trường hợp đặc biệt).

Nguyên tắc hoạt động của kiến ​​trúc hai tầng tương tác máy khách-máy chủ là quá trình xử lý yêu cầu xảy ra trên một máy chủ mà không liên quan đến các máy chủ khác trong quá trình xử lý này.

Mô hình tương tác máy khách-máy chủ hai tầng có thể được vẽ dưới dạng sơ đồ đơn giản.

kiến trúc client-server hai tầng

Ở đây bạn có thể thấy rằng cấp độ đầu tiên là mọi thứ liên quan đến máy khách và cấp độ thứ hai là mọi thứ liên quan đến máy chủ.