RabbitMQ – Một message queue phổ biến mà dev nào cũng nên biết

RabbitMQ – Một message queue phổ biến mà dev nào cũng nên biết

August 17, 2021 4 By Nam Vu

Ở bài viết về Microservice Communication mình đã đề cập tới message queue một trong những phương thức giao tiếp phổ biến trong microservice. Bạn có thể đọc lại tại đây
http://blog.ntechdevelopers.com/giao-tiep-trong-microservices/

Và một trong những thư viện mã nguồn mở cũng như một message broker đó chính là RabbitMQ. Đây cũng là một thư viện được dùng phổ biến nhất mà các developers nên biết.
Cùng mình tìm hiểu RabbitMQ là gì và khi nào nên sử dụng nó nhé!

Ở bài viết trước mình đã ví Message Broker là một nhà môi giới, khi bạn cần bán một thứ gì đó, bạn tìm đến nó, khi những cần mua bạn cũng tìm đến nó. Vậy định nghĩa chính xác của nó sẽ như sau.

RabbitMQ là một message broker (message-oriented middleware), một nhà môi giới mã nguồn mở. Nó sử dụng giao thức AMQP – Advanced Message Queue Protocol, một giao thức nâng cao phổ biến có thể gửi dữ liệu (message) thông qua cơ chế hàng đợi. Thực tế ban đầu chỉ là AMQP nhưng sau đó đã được phát triển để hỗ trợ Streaming Text Oriented Messaging Protocol (STOMP), Message Queuing Telemetry Transport (MQTT), và những giao thức khác

Để hiểu rõ hơn thì mình sẽ lấy ví dụ chuyển phát thư qua đường bưu điện xuyên suốt bài viết này nhé!

Đầu tiên là các thuật ngữ cơ bản trong RabbitMQ

ntechdevelopers

Producer: Phía bên đảm nhận việc gửi message. Bạn có thể xem đây là người cần gửi thư cho một ai đó.
Consumer: Phía bên đảm nhận việc nhận message. Bạn có thể xem đây là người nhận được thư mà ai đó gửi tới.
Message: Thông tin dữ liệu truyền từ Producer đến Consumer. Đây chính là thư được gửi đi chứa nội dung gửi, nó có thể là thư tay, hàng hóa, bưu phẩm…
Queue: Nơi lưu trữ messages. Bạn có thể xem đây là một hòm lưu trữ thư với cơ chế, ai gửi trước thì được chuyển phát trước (First in first out)
Connection: Kết nối giữa ứng dụng và RabbitMQ broker. Đây có thể coi là các bưu điện đặt tại các tỉnh thành, khi bạn gửi thư thì bạn sẽ phải ra bưu điện đúng không nào
Channel: Một kết nối ảo trong một Connection. Quá trình gửi và nhận sẽ có một sợi dây liên kết trung gian, khi bạn muốn gửi một bưu phẩm, bạn sẽ phải ghi thông tin người gửi, người nhận lên trên một tờ phiếu gửi nhận, từ đó bưu điện sẽ dựa vào thông tin đó mà chuyển bưu phẩm giúp bạn.
Exchange: Là nơi nhận message được publish từ Producer và đẩy chúng vào queue dựa vào quy tắc của từng loại Exchange. Có thể hiểu đây là một khu vực kho tổng hợp tất cả các thư mà mọi người gửi thư tới được tổng hợp, phân loại khu vực, gửi hàng loạt hay không…
Binding: Đảm nhận nhiệm vụ liên kết giữa Exchange và Queue. Có thể xem đây là quá trình chuyển thừ hòm lưu trữ thư vào kho phân loại.
Routing key: Một key mà Exchange dựa vào đó để quyết định cách để định tuyến message đến queue. Khi kiểm tra địa chỉ trên mỗi bức thư thì Routing key chính là địa chỉ người nhận, khi này việc phân loại thư trong kho sẽ phân loại dựa theo địa chỉ này để đưa tới từng khu vực bưu điện đích.
AMQP: Giao thức Advance Message Queuing Protocol, là giao thức truyền message trong RabbitMQ. Có thể xem đây là một trong những hình thức chuyển phát bưu phẩm, có thể là chuyển phát nhanh, chuyển phát thường, chuyển phát đảm bảo…
User: Gồm username và password giúp truy cập vào RabbitMQ dashboard hoặc tạo connection. Có thể xem đây là những nhân viên bưu điện, họ có thể theo dõi, phân loại, can thiệp, hỗ trợ trong quá trình gửi bưu phẩm.
Virtual host/Vhost: Cung cấp những cách riêng biệt để các ứng dụng dùng chung một RabbitMQ instance. Hãy xem đây là những bưu cục chi nhánh rải trên khắp đất nước để thuận tiện cho người gửi cũng như người nhận.

ntechdevelopers

Đến đây thì bạn lại tò mò rằng tại sao lại là RabbitMQ. Thực ra để trả lời được câu hỏi này thì trong bài viết “Messages Queue – Cách mà Microservice giao tiếp với nhau” mình cũng đã có đề cập đến ưu và nhược điểm của message queue rồi, bạn có thể xem lại.

RabbitMQ nó là Message Queue nên nó cũng không ngoại lệ, nó nhắm giải quyết các bài toàn của Message Queue như bất đồng bộ, hệ thống phân tán, hay bài toán xử lý truyền dữ liệu hàng loạt.

Quay lại câu chuyện gửi thư thì chẳng ai muốn tự mình đi gửi thư hàng nghìn cây số và đợi phản hồi đúng không ạ, cũng chẳng ai tự mình gửi từng chiếc thư cảm ơn tới một tập hàng triệu khách hàng, điều này tốn rất nhiều thời gian cũng như chi phí để hoàn thành. Vậy nên họ sẽ chọn giải pháp ký gửi một đên thứ 3 như bưu điện để làm việc này giúp mình.

ntechdevelopers

Bên cạnh những ưu điểm nằm trong Message Queue thì RabbitMQ được cho là tốt hơn so với những nền tảng Message Queue khác. Trên trang chủ của Rabbit thì có thể liệt kê ra một số tính năng hay ho mà nó hỗ trợ như:
– Độ tin cậy cao
– Routing linh hoạt
– Tối ưu máy chủ clustering
– Tính liên kết phù hợp
– Tính sẵn sàng cao
– Hỗ trợ nhiều giao thức
– Đa dạng các ứng dung
– Hỗ trợ giao diện quản lý
– Hỗ trợ tính năng truy vết
– Có thể mở rộng với nhiều plugin

Thực tế thì chỉ có 3 ưu điểm chính mà các anh em lập trình viên lựa chọn nó thay vì các nền tảng khác đó là: Mã nguồn mở (miễn phí); Dễ dàng sử dụng và hỗ trợ nhiều giao thức cũng như nhiều ngôn ngữ khác nhau; Hiệu suất được đánh giá là tốt. Bạn đọc có thể tham khảo thêm về mức độ đánh giá của cộng đồng reviewer tại đây cho RabbitMQ nhé

ntechdevelopers

Cùng với gRPC mà mình giới thiệu trong bài viết trước, mình thấy RabbitMQ là một lựa chọn không tối đối với Microservices. Nếu bạn đang tìm hiểu về loại Message Queue này có thể tìm hiểu kỹ hơn trong document chính quy này nhé. https://www.rabbitmq.com/documentation.html

Tiếp theo mình sẽ đi sơ lược về cơ chết hoạt động của RabbitMQ nhé!

Việc đầu tiên khi chúng ta đi gửi bưu phẩm là gì? Tất nhiên là chuẩn bị bưu phẩm, định nghĩa các đối tượng message. 

Tiếp đó là tạo connection và channel phía người gửi, điều này đồng nghĩa với việc bạn mang bưu phẩm ra bưu cục gần nhất rồi, Ở đây bạn sẽ phải ghi địa chỉ gửi, và chọn hình thức gửi hàng loạt tới nhiều người hay chỉ định gửi tới một người. Quá trình tạo connection và channel này cũng được thực hiện bên phía người nhận. Có thể người nhận đăng ký tôi sẽ nhận thư này khi người gửi có bưu phẩm mới, đây chính là cơ chế publisher/consumer khi truyền và nhận message. Việc chọn loại và hình thức nhận bưu phẩm này sẽ giúp cho Exchange phân loại được bưu phẩm nào được gửi tới đâu được dễ dàng hơn. Mình sẽ nói các loại Exchange ở bên dưới sau.

ntechdevelopers

Sau khi Producer đẩy message vào Exchange, Exchange nhận Message, nó phân loại chúng và binding các message này từ Exchange đến Queue. Việc này giống như nhân viên bưu cục phân loại thư vào từng khu vực vậy, mỗi khu vực có một số thư cần nhận, họ xếp chúng vào hòm lưu trữ và vận chuyển đến bưu cục đích.

Các Message nằm ở Queue và được vận chuyển đến khi lượt message nào thì message đó được xử lý bởi một Consumer. Consumer xử lý message nhận từ Queue với đúng Routing Key. Việc này bạn có thể hình dung các anh đưa bưu phẩm dựa vào địa chỉ trên mỗi bưu phẩm và chuyển tới từng người nhận một, nó được chuyển lần lượt và chuyển theo hàng đợi, gửi sớm thì nhận được sớm.Sau khi người nhận nhận được bưu phẩm thì đồng nghĩa với việc comsumer hoàn thành nhiệm vụ và tất nhân message trong queue sẽ bị mất đi.

Những bưu phẩm nào không thể consume thì nó sẽ được đẩy vào Dead Letter Exchange, một kho chứa những những message không thể gửi được. Ở đây bưu phẩm sẽ được xử lý với những action tương ứng như retry, reject với expired time

Ok, đó chính là một quy trình gửi message của RabbitMQ. Giờ thì cùng mình tìm hiểu các loại Exchange mà mình để cập trong quy trình trên nhé!

– Direct Exchange vận chuyển message đến queue dựa vào routing key

ntechdevelopers

– Default Exchange, Mỗi một exchange đều được đặt một tên không trùng nhau, default exchange bản chất là một direct exchange nhưng không có tên (string rỗng)

– Fanout Exchange định tuyến message tới tất cả queue mà nó bao quanh, routing key bị bỏ qua

ntechdevelopers

– Topic Exchange định tuyến message tới một hoặc nhiều queue dựa trên sự trùng khớp giữa routing key và pattern

ntechdevelopers

– Header Exchange được thiết kế để định tuyến với nhiều thuộc tính, dễ dàng thực hiện dưới dạng header message thay vì routing key

ntechdevelopers

Trên đây là sơ lược về RabbitMQ cũng như cách thực hoạt động của nó, hi vọng bài viết có thể giúp bạn hình dung được quá trình thực hiện trao đổi dữ liệu của một trong những loại Message Queue phổ biết nhất thời điểm hiện tại. 

Có thể đây sẽ chỉ là cơ chế giúp bạn hiểu được rõ hơn thông qua ví dụ chuyển bưu phẩm khi sử dụng RabbitMQ thuần. Trong thực tế có một số thư viện hỗ trợ và trừu tượng hóa những tính năng này trong rabbitMQ mà không hẳn là sử dụng rabbitMQ thuần như hiện tại. Mình sẽ có những bài viết khác để nói về vấn đề này chi tiết hơn.


#ntechdevelopers