RabbitMQ thuần và cách sử dụng chúng

RabbitMQ thuần và cách sử dụng chúng

October 2, 2021 1 By Nam Vu

Bài viết trước mình có giới thiệu với các bạn về “RabbitMQ – Một message queue phổ biến mà dev nào cũng nên biết” cũng như nói về cách thức hoạt động của RabbitMQ là như thế nào. Ở bài viết này hãy cùng mình đi tiếp chủ đề khi nào nên sử dụng RabbitMQ và cách sử dụng chúng như thế nào nhé!

Bắt đầu thôi!

RabbitMQ cũng như một số các AMQP (Advanced Message Queuing Protocol) khác chúng sinh ra nhằm mục đích là một nhà môi giới các messages, những bức thư được chuyển cho người nhận thông qua các cục bưu điện. Vậy thì khi nào chúng ta cần gửi thư?

Một ví dụ thật sự buồn cười nhưng mà để trả lời cho câu hỏi này thì bạn cũng sẽ hiểu được khi nào thì cần dùng Message Queue.

Asynchronously task

Phải nói đây là trường hợp đầu tiên mà bạn sử dụng Message Queue. Khi service A gửi một tín hiệu hay một dữ liệu nào đó cho service B mà không cần phải chờ kết quả trả về, chúng được thực hiện hóa một cách bất đồng bộ. Khi này hãy nghĩ tới rabbitmq xem. Nó sẽ giúp tiến trình của bạn sẽ được tiếp tục và bạn sẽ phó mặc cho consumer thực thi yêu cầu của bạn, việc bạn cần làm là gửi thư, còn thư khi nào gửi và gửi tới khi nào, là việc sắp xếp của bưu cục. Khi nào gửi được nó sẽ báo lại cho bạn mà bạn không cần phải ngồi chờ đợi thư tình của mình gửi được chưa vậy, mất công mất việc của bạn quá!

Background parallel task

Cũng tương tự như việc bất đồng bộ và tối ưu quy trình và trải nghiệm người dùng, không bắt họ phải chờ đợi thì bạn cũng dùng cách này để thực hiện hóa song song tất cả các tác vụ của bạn dưới background. Một ví dụ hay được sử dụng nhất chính là tổng hợp dữ liệu, đồng bộ dự liệu từ bên thứ ba hay một hệ thống nào khác đưa vào hệ thống của bạn, dữ liệu quá nhiều và thay đổi khi có dữ liệu mới. Khi này bạn không thể đợi và canh me khi nào thì trigger luồng tổng hợp dữ liệu được. Bạn sẽ thường bắn một event rabbitmq để lợi dụng tính đa luồng và độc lập của nó nhằm đồng bộ hóa dữ liệu một cách song song và ngầm định bên dưới, các dữ liệu của bạn sẽ chạy độc lập và không bị phụ thuộc mới nhau. Mỗi message trong message queue của rabbit sẽ là một tín hiệu đồng bộ riêng rẽ, dữ liệu này fail sẽ không ảnh hưởng đến dữ liệu khác.

Push message to client

Một trong những trường hợp hay dùng nữa là thông báo từ server cho client một dữ liệu nào đó. Facebook hay Zalo cũng có những cơ chế riêng để thông báo newfeeds và notifications cho người dùng thông qua message queue. Khi này rabbitmq cũng là một sự lựa chọn thích hợp, nó cũng có một giao thức MQTT nhắm hỗ trợ connect với các thiết bị phần cứng hay những ứng dụng di động nhằm thông báo những thay đổi hay điều khiển bổ trợ cho các ứng dụng IOT nữa. 

Trên đây là những trường hợp phổ biến nhất để bạn có thể nghĩ tới message queue cũng như rabbitmq.

Phần tiếp theo cùng mình đi tìm hiểu thử làm thế nào để thực hiện hóa một ứng dụng rabbitmq thuận nhé! 

Tại sao mình nói là thuần vì hiện tại có rất nhiều thư viện đã hỗ trợ thực hiện hóa và bọc lại những thứ phức tạp của rabbit hay trừu tượng hóa nhằm hỗ trợ nhiều loại message queue hơn mà không riêng gì RabbitMQ. Ngoài ra còn cò một loạt các cloud message queue hỗ trợ vấn đề này rồi. Vậy nên ở bài viết này mình chỉ đề cập đến RabbitMQ thuần, bài viết sau mình sẽ đề cập đến các thư viện và cloud hỗ trợ kia sau nhé

Bước 1: Cài đặt RabbitMQ

Để cài đặt rabbitmq thì mình có 2 cách:

– Đầu tiên là tải chương trình về và cài đặt vào máy, nó tương tự như tải và cài đặt phần mềm bất kỳ nào đó trong máy tính của bạn, có thể máy tính bạn là Windows, OS hay Ubuntu thì cũng sẽ có những chương trình tương ứng để bạn tải và cài đặt

– Cách thử 2 là qua docker hay docker-composer. Docker xuất hiện thì tất nhiên những thành phần trước đó cũng phải thay đổi để thích nghi chứ, RabbitMQ đã đóng gói thành những image để có thể hoạt động trên docker tương tự như các ứng dụng khác. Việc của bạn cần làm lúc này là kéo nó về và chạy nó trên docker mà thôi. Câu lệnh kéo image và run dưới đây nhé!

docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.9-management

Ngoài ra để tránh việc build up liên tục mỗi lần bật tắt máy thì bạn dùng docker-composer để có thể chạy rabbit cùng với các ứng dụng khác cũng không vấn đề. Tham khảo docker-composer sau của mình nhé!

Bước 2: Tạo services gửi và nhận đi kèm contract giữa bên gửi và nhận messages

Nếu bạn muốn gửi thư, thì bạn phải có thư, nếu bạn muốn gửi dữ liệu thì bạn phải có dữ liệu. Vậy nên bạn cần tạo ra những class object để chứa dữ liệu của bạn. Đồng thời phải xác định và thiết lập phía gửi và phía nhận một cách rõ ràng. Bạn có thể gửi message dưới dạng stardard, worker-queue, publisher-subcriber, hay direct-routing (Nó là các loại RabbitMQ mà mình đã giới thiệu trong bài viết trước và mình sẽ demo từng loại ở github của mình nhé!)

Bước 3: Viết phần kết nối service phía gửi và phía nhận với RabbitMQ

Tất nhiên là khi muốn gửi thư thì bạn phải mang thư ra bưu cục và xác định rõ địa chỉ cho chúng rồi. Khi này việc thiết lập với rabbitmq sẽ giúp bạn xác định message được gửi đi đâu và phân bổ đúng nơi bạn muốn đến

– Ở phía gửi thì bạn tạo connection tới queue mà bạn định nghĩa

– Ở phía nhận bạn cũng tạo connection tới queue giống như bên gửi để có thể nhận chính xác thư bên gửi

Bước 4: Viết send message và consume message

Sau khi kết nối với rabbitmq thì xem như bạn đã thông luồng message rồi, việc còn lại của bạn là xác lập gửi thư và nhận thư. Khi nào bạn gửi? Khi bạn gọi hàm send message và truyền message thông qua contract được định nghĩa ở bước 1. Khi nào bạn nhận được thư? Khi bạn viết định nghĩa consumer để có thể nhận message theo contract định sẵn. Mặc định thì RabbitMQ có hỗ trợ cho bạn QueueBassicConsumer để hỗ trợ việc nhận message, tuy nhiên bạn cũng có thể tự mình viết những consumer khác tùy theo mục đích và yêu cầu cầu của bạn.

Trên đây là 4 bước để bạn có thể thực hiện hóa một chương trình với rabbitmq, mình sẽ để source code demo tại đây để bạn tham khảo.

Sau khi bạn gửi message bạn có thể vào dashboard của RabbitMQ local của bạn để kiểm tra message tại địa chỉ và account mặc định bên dưới

Url: http://localhost:15672/
Username default: guest
Password default: guest

Nếu message của bạn mới chỉ send mà chưa được consume thì nó sẽ nằm trên rabbitMQ (Như bạn thấy trong hình của mình có 13 message chưa được consume)

Bạn có thể get và kiểm tra message của bạn trong queue tại thời điểm này

Khi bạn chạy consume service lên thì message của bạn sẽ được nhận và ngay lập tức message trên queue của bạn sẽ biến mất do đã được chuyển tới người nhận thành công.

Trong demo sẽ có 4 lọa demo khác nhau bạn có thể tìm hiểu thêm, tuy nhiên mình nhấn mạnh một chút là loại pub/sub và loại direct routing sẽ giúp bạn gửi 1 message cho nhiều consumer cùng 1 lúc nếu chúng cùng được đăng ký tới 1 queue name. 

Tuy rằng RabbitMQ thuần này vẫn có thể đáp ứng nhu cầu của bạn, nhưng trong thực tế thì sẽ có rất nhiều thư viện hỗ trợ làm đơn giản hóa quá trình implement này đi. Vậy nên đây chỉ là một cách implement sơ khai nhất thôi nhé. Bài viết sau mình sẽ viết về một trong số các thư viện hỗ trợ RabbitMQ mà được sử dụng nhiều trong thực tế. Đón đọc nhé! 

Và giờ, chúc bạn khám phá thành công với công nghệ này!

#ntechdevelopers