Tìm Hiểu Kỹ Thuật MESSAGING

Kỹ thuật Messaging là một kỹ thuật rất phổ biến trong các dự án phần mềm hiện nay và việc phát triển phần mềm không còn giới hạn trên một nền tảng cụ thể nào nữa. Vì vậy câu hỏi đặt ra là làm sao để các dịch vụ có thể giao tiếp với nhau một cách hiệu quả? Kỹ thuật Messaging chính là câu trả lời.

Tìm Hiểu Kỹ Thuật MESSAGING

1. Tổng quát về kỹ thuật Messaging

Kỹ thuật Messaging là một kỹ thuật giúp các dịch vụ, ứng dụng giao tiếp với nhau thông qua việc gửi và nhận gói tin dưới dạng text-based thông qua network, các gói tin sẽ được gửi tuần tự theo dạng FIFO (First In First Out). Thường thì kích thước gói tin khá nhỏ, nó chỉ chứa đủ thông tin cần thiết để các dịch vụ có thể hiểu và giao tiếp lẫn nhau nên chúng ta không cần thiết phải gửi một gói tin quá lớn, nếu bạn áp dụng kỹ thuật này để truyền tải một gói tin lớn thì xin chia buồn có lẽ bạn đang tiếp cận sai giải pháp.

 

Hình 1. Ứng dụng giao tiếp thông qua messages

Trước khi đi tới phần tiếp theo, mình muốn dừng lại một chút hỏi các bạn rằng tại sao chúng ta lại cần quan tâm đên kỹ thuật này trong vấn đề giao tiếp giữa các dịch vụ với nhau?, trong khi chỉ cần sử dụng một phương thức khá truyền thống là gọi Request HTTP trực tiếp giữa các dịch vụ, ứng dụng với nhau có phải nhanh và đơn giản hơn không?. Nhưng khoan, chúng ta hãy cùng nhau xem xét một vài ý sau đây:

 

Vấn đề về network: Chắc chắn rồi network chậm, không stable là việc chắc chắn xảy ra. Việc này dẫn đến các Request dễ gặp lỗi timeout, rất khó trong việc đảm bảo được khả năng “failover and redundancy” (khả năng chịu lỗi và dự phòng) của hệ thống. 

Vấn đề về môi trường: Khác ngôn ngữ, khác công nghệ, khác cả môi trường hoạt động đều có thể dẫn tới sự khó khăn khi integrate các dịch vụ với nhau vì vậy chúng ta cần suy nghĩ về một giải pháp nào đó đóng vai trò là một interface chung.

Sự thay đổi logic của các endpoint: Các endpoint có thể được thay đổi, cập nhật trong suốt quá trình phát triển của dự án, thậm chí là khi đã lên môi trường production. Điều này dẫn đến việc rất khó quản lý và tốn khá nhiều công sức trong việc cập nhật lại thông tin để đồng bộ lại các request giữa các dịch vụ với nhau.

 

Điểm qua các vấn đề phía trên thì việc lựa chọn kỹ thuật Messaging hoàn toàn phụ hợp để khắc phục các vấn đề này, nhưng vì sao nó phù hợp và giải quyết được các vấn đề nêu trên? Hãy đi sâu hơn nội dung bên dưới để nắm rõ kỹ thuật này.

 

Messaging là một kỹ thuật cho phép các dịch vụ, ứng dụng  giao tiếp với nhau dưới dạng bất động bộ (Asynchronous), có nghĩa là gì?. Có nghĩa là các ứng dụng không cần phải chờ nhau trong quá trình giao tiếp so với phương pháp dùng Request Http trực tiếp.

Các thành phần chính trong kỹ thuật Messaging

Sender/Publisher: Ứng dụng / Dịch vụ gửi message.

Receiver/Subscriber: Ứng dụng / Dịch vụ nhận message.

Storage: Nơi lưu trữ các messages (thông thường sẽ sử dụng cấu trúc dữ liệu hàng đợi), tại đây các ứng dụng gửi và nhận dữ liệu sẽ giao tiếp với nhau thông qua một Storage duy nhất.

Message Broker: Bao gồm một broker server để quản lý các remote connection, storages và một distributor chịu trách nhiệm phân phối các messages tới những Receivers.

 

Những pattern để sử dụng kỹ thuật Messaging

Message Queue: Pattern này hoạt động theo nguyên tắt one to one, nghĩa là một sender sẽ chỉ gửi message tới một receiver duy nhất, trường hợp nếu  có nhiều receiver cùng lắng nghe từ một queue storage thì chỉ cần một trong các receiver nhận được message các receiver còn lại sẽ không thể nhận được message.

Pub/Sub: Pattern này hoạt động theo nguyên tắt one to many, nghĩa là một publisher sẽ có thể gửi message tới nhiều subscriber cùng một lúc

 

Hình 2. Các thành phần khi triển khai kỹ thuật messaging

 

Bất kỳ công nghệ hay kỹ thuật nào cũng đều có những thuận lợi và khó khăn nhất định, vì vậy kỹ thuật Messaging cũng không phải là ngoại lệ. Hãy cùng điểm qua các thuận lớn và khó khăn của kỹ thuật này

Lợi ích của kỹ thuật Messaging

  • Dễ dàng scale và không ảnh hưởng tới các dịch vụ khác: Để sử dụng kỹ thuật này chúng ta sẽ cần host một Broker chạy độc lập hoàn toàn với với ứng dụng khác vì vậy việc scale trở nên khá dễ dàng.
  • Độ sẵn sàng cao: Các dịch vụ / ứng dụng không bao giờ rơi vào trạng thái bị thắt cổ chai do phải đợi nhau hoàn thành một công việc nào đó bởi vì messaging sử dụng kỹ thuật asynchronous.
  • Đảm bảo tính stable của hệ thống: Giả sử bạn cần gửi email từ hệ thống, bạn dùng cách làm truyền thống khi thực thì xong một công việc nào đó bạn gọi hàm gửi mail ngay lập tức, một hoặc vài email thì không sao nhưng thử nghĩ nếu chúng ta phải gửi hàng ngàn email? Lúc này có thể dẫn ứng dụng không ổn định (chậm or thậm chí bị shutdown).
  • Truyền dữ liệu nhanh: Kỹ thuật thông thường hay sử dụng socket / websocket để truyền tải dữ liệu trực tiếp nên tốc độ nhanh hơn Request Http rất nhiều (thật ra bên trong http vẫn sử dụng kỹ thuật socket, nhưng server cần phải đi phân giải DNS trước nên tốc độ sẽ không nhanh hơn tcp/ip trực tiếp và http thường có timeout ngắn).

Khó khăn của kỹ thuật Messaging

  • Log và Monitor: Luôn cần phải xây dựng thêm hệ thống log và monitor cho messaging bởi vì bạn không thể tự tin rằng việc gửi và nhận message không có lỗi.
  • Retry Action: Phải thiết kế cơ chế cho phép retry lại action của message trong trường hợp có lỗi xảy ra.
  • Chờ phản hồi: Khi cần nhận phản hồi ngay lập tức hầu như kỹ thuật này chưa đáp ứng được mà thường cần kết hợp thêm một vài kỹ thuật khác.
  • Duy trì connection: Connection có thể bị mất kết nối trong một vài trường hợp như server quá tải, network yếu vì vậy cần phải thiết lập một cơ chế cho phép tự động kết nối lại khi kết nối bị đứt.

2. Kỹ thuật cơ bản để xây dựng một Messaging

Việc nghiên cứu và tự xây dựng một Message Broker là một kỹ thuật khó và nó không hề đơn giản vì vậy trong phạm vi của phần này mình chỉ trình bày cách thiết kế và những thành phần cơ bản cần phải có khi bắt đầu tự xây dựng một Message Broker, cũng như cung cấp kiến thức nền tảng để các bạn của thể tự nghiên cứu xây dựng riêng cho mình một Message Broker.

 

Lưu ý rằng mình sẽ không liệt kê toàn bộ source code ở đây mà thay vào đó sẽ chỉ ra các ý chính, vấn đề cần nắm khi xây dựng Message Broker. Còn source code cài đặt đầy đủ các bạn có thể tham khảo tại đây: Messaging Sample

Phân tích bài toán:

Điểm qua nội dung ở phần tổng quát phía trên thì bài toán của chúng ta cần xây dựng phải đáp ứng được các nhiệm vụ cơ bản sau:

  • Cho phép ứng dụng bên ngoài kết nối vào với vai trò là sender hoặc receiver.
  • Phải duy trì được kết nối lâu dài.
  • Cho phép sender và receiver trao đổi thông tin với nhau thông qua một storage cụ thể.
  • Hỗ trợ được hai pattern phổ biến là Message Queue và Pub/Sub.

Xác định các thành phần chính:

  1. Một message server đóng vai trò tiếp nhận và quản lý các connection từ các ứng dụng / dịch vụ client.
  2. Một message broker nằm ở phía server (1)  chịu trách nhiệm quản lý message, storage và phân phối message giữa các client với nhau.
  3. Để đơn giản hóa công việc của message broker (2) mình sẽ cần thiết kê thêm một Distributor chịu trách nhiệm phân phối các message, Distributor này sẽ được inject vào trong message broker.
  4. Storage để lưu trữ các message, storage này sẽ được nằm ở phía server (1) và được quản lý bởi message broker (2).
  5. Một Message Client library cho các ứng dụng / dịch vụ đầu cuối, thư viện này đóng vai trò là một wrapper cho các hàm như connect tới server, lắng nghe phản hồi từ message broker, gửi message tới message broker...

Lựa chọn công nghệ và kỹ thuật:

  1. Ngôn ngữ và môi trường: C# và Net6, (bạn có thể dụng ngôn ngữ nào bạn thích cũng được không quan trọng nhưng phải đảm bảo có đủ thư viện, tài liệu, và hỗ trợ lập trình bất động bộ).
  2. Server: Chúng ta sẽ dùng socket, socket cho phép gửi và nhận dữ liệu nhanh và đặt biệt nó stable có thể chấp nhận một lượng lớn connection và duy trì được connection một cách bền bỉ, lâu dài. Hầu hết các ứng dụng real-time hiện này đều sử dụng socket.
  3. Storage: Để đáp ứng được yêu cầu message phải được phân phối tuần tự theo nguyên tắc FIFO (First In First Out) chúng ta cần sử dụng cấu trúc dữ liệu hàng đợi (Queue).

Bắt tay vào việc thiết kế:

Xây dựng Message Broker Server:

Bắt đầu bằng việc tạo mới một đối tượng có tên là Message Server, để khởi tạo server bằng socket chúng ta không cần thiết phải cài đặt bất kỳ một thư viện của bên thứ ba nào cả bởi vì Microsoft đã phát triển sẵn thư viện  System.Net.Sockets vả được tích hợp sẵn trong .net / core framework.

Bên trong đối tượng này mình sẽ khai báo 2 property như sau:

  • IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 8100): Property này sử dụng để định nghĩa địa chỉ ip và port của server, client sẽ connection đến server thông qua địa chỉ này, IPAddress.Loopback tương đương với localhost (127.0.0.1), ở đây mình sẽ chỉ định port cho Server của mình là 8100 (các bạn có thể thay thế port nào tùy thích tuy nhiên phải bảo đảo port này chưa được sử dụng).
  • TcpListener listener = new TcpListener(endPoint); Property này có nhiệm vụ chờ để accept kết nối từ phía client.
  • Sử dụng vòng lặp while để cho phép server đứng chờ kết nối từ client.

 

Phần code đầy đủ cho Message Server sẽ như sau:

Hình 3. Message Server

Ở đây mình sử dụng vòng lặp while mục đích là cho phép server chấp nhận nhiều kết nối tới từ client, hàm listener.AcceptTcpClient() sẽ có cơ chế là dừng và chờ đợi cho tới khi có một kết nối vào.

OK, tới đây cơ bản chúng ta đã có một socket server hoàn chỉnh, công việc tiếp theo cần phải xây dựng cơ chế quản lý các session của client đã kết nối vào server cũng như thiết lập cách gửi và nhận message.

Source code chi tiết: MessageServer.cs.

 

Xây dựng Message Broker

Như đã phân tích ở trên thì Message Broker cần có Storage và một Component gọi là Distributor sẽ chịu trách nhiệm chính trong việc quản lý senders, receivers và phân phối các message giữa sender và receiver với nhau, vì vậy để tiến hành xây dựng Message Broker, chúng ta cần định nghĩa các đối tượng sau đây:

  • QueueStorage: Là nơi lưu trữ các messages trong Queue, rất may mắn là C# đã xây dựng sẵn một đối tượng có tên là Queue để hỗ trợ chúng ta lưu trữ dữ liệu theo cấu trúc hàng đợi. Trong queue này chúng ta cần định nghĩa thêm một thuộc tính để phân biệt Queue này dành cho Queue Pattern hay Queue dạng Topic Pattern. 

Source code chi tiết: QueueStorage.cs.

  • StorageManagement: Một Message Broker không thể chỉ có một Queue được mà sẽ có rất nhiều Queue mỗi Queue sẽ lưu trữ các messages cho các mục đích nghiệp vụ khác nhau vì vậy đối tượng này sẽ quản lý danh sách các Queue trong Message Broker.

Source code chi tiết: StorageManagement.cs.

  • ClientSession: Chứa thông tin kết nối Tcp/Ip từ client, và một background thread lắng nghe message được gửi từ chính client này.

Source code chi tiết: ClientSession.cs.

  • Distributor: Có nhiệm vụ quản lý client và phân phối message nên ở đây chúng ta cần thiết kế hai danh sách có cùng kiểu dữ liệu ClientSession, một để quản lý các Senders và một để quản lý các Receivers và đối tượng. Ở đối tượng Distributor này chúng ta sẽ thiết kế thêm hai background thread dùng để phân phối các messages, một thread dùng để phân phối theo Queue Pattern, thread còn lại dùng để phân phối message theo Topic Pattern.

Source code chi tiết: Distributer.cs.

  • MessageBroker: Cuối cùng đây sẽ là nhân vật chính của chúng ta cần phải xây dựng. MessageBroker, MessageBroker sẽ đảm nhận nhiệm vụ chính là thực thi quản lý kết nối, phân phối các Messages vì vậy mình sẽ xây dựng các hàm và property sau đây:
    • Property Distributor: Chịu trách nhiệm phân phối các messages.
    • AcceptClient(): Tiếp Nhận connection từ client.
    • AcceptMessage(): Tiếp nhận message được gửi từ client.
    • AddSubscriber(): Subscribe client vào một queue hoặc topic bất kỳ.
    • RemoveSubcriber(): Xóa subscribe của client từ queue hoặc topic.

Source code chi tiết: MessageBroker.cs.

 

Sơ đồ thiết kế chi tiết:

Hình 4. Sơ đồ chi tiết của Message Broker

Nhìn vào sơ đồ trên các bạn có thể dễ dàng nhận thấy rằng thật ra Sender và Receiver giao tiếp với nhau một cách gián tiếp thông qua Socket Server và MessageBroker chịu trách nhiệm chính trong việc phân phối các messages.

3.  Tìm hiểu một vài Message Provider có sẵn

Hiện nay Messaging được sử dụng rộng rãi và phổ biến vậy nên một số tổ chức / công ty đã phát triển sẵn các Message Broker tối ưu và mạnh mẽ nên chúng ta không nhất thiết phải bỏ khá nhiều thời gian để tự xây dựng một Message Broker. Các bạn có thể tìm hiểu một số các Message Broker phổ biến sau đây:

 RabbitMQ: RabbitMQ là một message broker miễn phí có giao diện trực quan, dễ dàng quản lý và theo dõi các hoạt động của messing. Bạn có thể cài đặt và tìm hiểu RabbitMQ qua link: RabbitMQ.

Azure Service Bus: Đây là một message broker được phát triển bởi Microsoft và được vận hành trên môi trường Azure Cloud tùy nhiên khác với RabbitMQ vì được chạy trên môi trường đám mây của Microsoft nên sẽ có phí trong lúc sử dụng nhưng lợi ích mà bạn không cần phải quan tâm đến việc xây dựng infrastructure và monitor bởi vì Microsoft đã tích hợp sẵn mọi thứ. Link tham khảo: Azure Service Bus

Kafka: Kafka là một Message Broker mã nguồn mỡ được phát triển bởi tổ chức Apache chạy trên hệ thống phân tán, Kafka được đánh giá là có khả năng truyền tải dữ liệu rất nhanh theo thời gian thực. Link tham khảo: Kafka.

Amazon SQS Queue: Tương tự như Azure Service Bus, đây là một Message Broker được phát triển với Amazon và được vận hành trên Amazon Cloud, nền tảng cloud computing lớn nhất hiện nay. Link tham khảo: Amazon SQS.

4. Kết Luận

Đến đây mình hy vọng bài viết này sẽ cung cấp kiến thức cơ bản về Messaging cũng như tạo tiền đề để các bạn có thể tự nghiên cứu xây dựng một Message Broker cho riêng mình. Kiến thức này là rất hữu ích và quan trọng trong lĩnh vực phát triển phần mềm hiện nay nhất là các hệ thống về IOT (Các thiết bị giao tiếp với hệ thống bằng cách gửi tin hiệu / message) hoặc các hệ thống triển khai theo kiến trúc Microservices.



Leave a comment

Submit with


Comments (0)

saigon_technology

Related articles

Azure Function Overview

calendar

19 May 2023

time

6 mins read

Implement a distributed transaction in microservices software system using Saga pattern

calendar

19 May 2023

time

9 mins read

Azure Cosmos DB Overview

calendar

29 Mar 2023

time

5 mins read

career_saigon_technology

Quick Links

Opening Jobs

About us

Life at saigontechnology

Blog

Contact Us

PRIVACY POLICY

Follow Us

DMCA.com Protection Status
saigontechnology-great-plage-to-work-partner
saigontechnology-best-workplaces
saigontechnology-microsoft-partner
iso_9001iso_27001
sao_khue
50_leading

© Copyright 2023 by STS Software Technology JSC, Leading Software Outsourcing Company in Vietnam. All Rights Reserved.

We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.