GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Message Queue Giới thiệu RabbitMQ

Giới thiệu RabbitMQ

Đăng vào 11/05/2020 . Được đăng bởi GP Coder . 20988 Lượt xem . Toàn màn hình

Trong các bài viết trước chúng ta đã tìm hiểu về JMS và ActiveMQ. Trong bài này, chúng ta sẽ tìm hiểu một message broker khác là RabbitMQ.

Nội dung

  • 1 RabbitMQ là gì?
  • 2 Tại sao sử dụng RabbitMQ?
  • 3 Những khái niệm cơ bản trong RabbitMQ
  • 4 RabbitMQ hoạt động như thế nào?
  • 5 Exchange và các loại Exchange

RabbitMQ là gì?

RabbitMQ là một message Broker (MOM – Message-Oriented Middleware), sử dụng giao thức AMQP (Advanced Message Queue Protocol).

RabbitMQ được viết bằng ngôn ngữ Erlang.

RabbitMQ là một phần mềm trung gian được sử dụng để trao đổi dữ liệu giữa các process, application, system hoặc server. RabbitMQ sẽ nhận message đến từ các thành phần khác nhau trong hệ thống, lưu trữ chúng an toàn trước khi đẩy đến đích.

RabbitMQ chạy trên nhiều OS, Cloud và cung cấp một loạt các công cụ dành cho nhà phát triển với hầu hết các ngôn ngữ phổ biến.

RabbitMQ không phải là một JMS Provider, nhưng nó cung cấp plugin cần thiết hỗ trợ mô hình JMS Queue và JMS Topic.

Tại sao sử dụng RabbitMQ?

Vấn đề

Giả sử chúng ta có một web application cho phép user đăng ký thông tin. Sau khi đăng ký, hệ thống sẽ xử lý thông tin, generate PDF và gửi email lại user. Những công việc này hệ thống cần nhiều thời gian để xử lý, chẳng hạn. Nếu xử lý theo cách thông thường thì user sẽ phải chờ đến khi hệ thống xử lý hoàn thành, và nếu hệ thống có hàng nghìn user truy cập cùng lúc sẽ gây quá tải server.

Đối với những loại công việc thế này, chúng ta sẽ xử lý nó bằng cách sử dụng message queue: Sau khi user nhập đầy đủ các thông tin trên web interface, web application sẽ tạo một Message “Generate PDF” chứa đầy đủ thông tin cần thiết và gửi nó vào Queue của RabbitMQ.

Đây là một architecture cơ bản của message queue.

  • Producer : là ứng dụng client, tạo message và publish tới broker.
  • Consumer : là ứng dụng client khác, kết nối đến queue, subscribe (đăng ký) và xử lý (consume) message.
  • Broker (RabbitMQ) : nhận message từ Producer, lưu trữ chúng an toàn trước khi được lấy từ Consumer.

Flow đầy đủ sử dụng RabbitMQ để giải quyết vấn đề trên:

  • (1) User gửi yêu cầu tạo PDF đến web application.
  • (2) Web application (Producer) gửi tin nhắn đến RabbitMQ bao gồm dữ liệu từ request như tên và email.
  • (3) Một Exchange chấp nhận các tin nhắn từ Producer và định tuyến chúng đến Queue (hàng đợi) để tạo PDF.
  • (4) Ứng dụng xử lý PDF (Consumer) nhận Message từ Queue và bắt đầu xử lý PDF.

Một số vấn đề khác:

  • Đối với các hệ thống sử dụng kiến trúc microservice thì việc gọi chéo giữa các service khá nhiều, khiến cho luồng xử lý khá phức tạp.
  • Mức độ trao đổi data giữa các thành phần tăng lên khiến cho việc lập trình trở nên khó khăn hơn (vấn đề maintain khá đau đầu).
  • Khi phát triển ứng dụng làm sao để các lập trình viên tập trung vào các domain, business logic thay vì các công việc trao đổi ở tầng infrastructure.
  • Với các hệ thống phân tán, khi việc giao tiếp giữa các thành phần với nhau đòi hỏi chúng cần phải biết nhau. Nhưng điều này gây rắc rối cho việc viết code. Một thành phần phải biết quá nhiều dẫn đến rất khó maintain, debug.

Lợi ích và tính năng của RabbitMQ

  • Transparency: Một producer không cần phải biết consumer. Nó chỉ việc gửi message đến các queue trong message broker. Consumer chỉ việc đăng ký nhận message từ các queue này.
  • Many Client: Vì producer giao tiếp với consumer trung gian qua message broker nên dù producer và consumer có khác biệt nhau về ngôn ngữ thì giao tiếp vẫn thành công. Hiện nay rabbitmq đã hỗ trợ rất nhiều ngôn ngữ khác nhau.
  • Asynchronous (bất đồng bộ): Producer không thể biết khi nào message đến được consumer hay khi nào message được consumer xử lý xong. Đối với producer, đẩy message đến message broker là xong việc. Consumer sẽ lấy message về khi nó muốn. Đặc tính này có thể được tận dụng để xây dựng các hệ thống lưu trữ và xử lý log.
  • Flexible Routing: message được định tuyến (route) thông qua Exchange trước khi đến Queue. RabbitMQ cung cấp một số loại Exchange thường dùng, chúng ta cũng có thể định nghĩa riêng Exhange cho riêng mình.
  • Lightweight: một single instance của RabbitMQ chỉ chiếm khoảng 40MB RAM.
  • Multiple message protocol: AMQP, MQTT, STOMP, HTTP.
  • Cluster: các bạn có thể gom nhiều rabbitmq instance vào một cluster. Một queue được đinh nghĩa trên một instance khi đó đều có thể truy xuất từ các instance còn lại. Có thể tận dụng để làm load balancing.
  • High availibilty: cho phép failover khi sử dụng mirror queue.
  • Reliability: có cơ chế ACK để đảm bảo message được nhận bởi consumer đã được xử lý, lưu trữ (persistence) message, .high availability, publisher confirm, …
  • Extensibility: cung cấp hệ thống plugin linh hoạt, dễ dàng tích hợp các plugin của third party. Ví dụ: plugin lưu message vào cơ sở dữ liệu.
  • Cloud: dễ dàng triển khai với hạ tầng hiện có hoặc Cloud.
  • Management & Monitoring: cung cấp HTTP API, command-line tool và UI để quản lý và giám sát.
  • Tools support: Hoạt động với các công cụ CI/CD và có thể triển khai với BOSH, Chef, Docker và Puppet.

Những khái niệm cơ bản trong RabbitMQ

  • Producer: Ứng dụng gửi message.
  • Consumer: Ứng dụng nhận message.
  • Queue: Lưu trữ messages.
  • Message: Thông tin truyền từ Producer đến Consumer qua RabbitMQ.
  • Connection: Một kết nối TCP giữa ứng dụng và RabbitMQ broker.
  • Channel: Một kết nối ảo trong một Connection. Việc publishing hoặc consuming message từ một queue đều được thực hiện trên channel.
  • 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. Để nhận được message, queue phải được nằm (binding) trong ít nhất 1 Exchange.
  • Binding: là quy tắc (rule) mà Exchange sử dụng để định tuyến Message đến Queue. Đảm nhận nhiệm vụ liên kết giữa Exchange và Queue.
  • Routing key: Một key mà Exchange dựa vào đó để quyết định cách để định tuyến message đến queue. Có thể hiểu nôm na, Routing key là địa chỉ dành cho message.
  • AMQP (Advance Message Queuing Protocol): là giao thức truyền message được sử dụng trong RabbitMQ.
  • User: Để có thể truy cập vào RabbitMQ, chúng ta phải có username và password. Trong RabbitMQ, mỗi user được chỉ định với một quyền hạn nào đó. User có thể được phân quyền đặc biệt cho một Vhost nào đó.
  • 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. Những user khác nhau có thể có các quyền khác nhau đối với vhost khác nhau. Queue và Exchange có thể được tạo, vì vậy chúng chỉ tồn tại trong một vhost.

RabbitMQ hoạt động như thế nào?

  • (1) Producer đẩy message vào Exchange. Khi tạo Exchange, bạn phải mô tả nó thuộc loại gì. Các loại Exchange sẽ được giải thích phía dưới.
  • (2) Sau khi Exchange nhận Message, nó chịu trách nhiệm định tuyến message. Exchange sẽ chịu trách nhiệm về các thuộc tính của Message, ví dụ routing key, loại Exchange.
  • (3) Việc binding phải được tạo từ Exchange đến Queue (hàng đợi). Trong trường hợp này, ta sẽ có hai binding đến hai hàng đợi khác nhau từ một Exchange. Exchange sẽ định tuyến Message vào các hàng đợi dựa trên thuộc tính của của từng Message.
  • (4) Các Message nằm ở hàng đợi đến khi chúng được xử lý bởi một Consumer.
  • (5) Consumer xử lý Message nhận từ Queue.

Exchange và các loại Exchange

Message không được publish trực tiếp vào Queue; thay vào đó, Producer gửi message đến Exchange.

Exchange là nơi mà các message được gởi. Exchange nhận tin nhắn và định tuyến nó đến 0 hoặc nhiều Queue với sự trợ giúp của các ràng buộc (binding) và các khóa định tuyến (routing key).

Thuật toán định tuyến được sử dụng phụ thuộc vào loại Exchange và quy tắc (còn gọi là ràng buộc hay binding).

Có 4 loại Exchange: Direct, Fanout, Topic, Headers. Lựa chọn các exchange type khác nhau sẽ dẫn đến các đối xử khác nhau của message broker với tin nhắn nhận được từ producer. Exchange được bind (liên kêt) đến một số Queue nhất định.

Exchange typeTên mặc định
Direct exchange(Empty string) hoặc amq.direct
Fanout exchangeamq.fanout
Topic exchangeamq.topic
Headers exchangeamq.match (và amq.headers trong RabbitMQ)

Ngoài Exchange type, Exchange còn định nghĩa một số thuộc tính:

  • Name: tên Exchange.
  • Durability: thời gian tồn tại khi broker restart
  • Auto-delete: exchange bị xóa khi hàng đợi cuối cùng không còn binding từ nó.
  • Arguments: các tham số không bắt buộc, được sử dụng bởi các plugin và các tính năng dành riêng cho broker.

Direct Exchange

Direct Exchange (trao đổi trực tiếp) định tuyến message đến Queue dựa vào routing key. Thường được sử dụng cho việc định tuyến tin nhắn unicast-đơn hướng (mặc dù nó có thể sử dụng cho định tuyến multicast-đa hướng). Các bước định tuyến message:

  • Một queue được ràng buộc với một direct exchange bởi một routing key K.
  • Khi có một message mới với routing key R đến direct exchange. Message sẽ được chuyển tới queue đó nếu R=K.

Một Exchange không xác định tên (empty ttring), đây là loại Default Exchange, một dạng đặc biệt của là Direct Exchange. Default Exchange được liên kết ngầm định với mọi Queue với khóa định tuyến bằng với tên Queue.

Direct Exchange hữu ích khi muốn phân biệt các thông báo được publish cho cùng một exchange bằng cách sử dụng một mã định danh chuỗi đơn giản.

Ví dụ, nếu hàng đợi (Queue) gắn với một exchange có binding key là pdf_create, message được đẩy vào exchange với routing key là pdf_create sẽ được đưa vào hàng đợi này.

Fanout Exchange

Fanout exchange định tuyến message (copy message) tới tất cả queue mà nó được bind, với bất kể một routing key nào. Giả sử, nếu nó N queue được bind bởi một Fanout exchange, khi một message mới published, exchange sẽ định tuyến message đó tới tất cả N queues. Fanout exchange được sử dụng cho định tuyến message broadcast (quảng bá).

Exchange Fanout hữu ích với trường hợp ta cần một dữ liệu được gửi tới nhiều ứng dụng khác nhau với cùng một message nhưng cách xử lý ở ứng dụng là khác nhau.

Topic Exchange (Publish/Subscribe)

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. Topic exchange thường sử dụng để thực hiện định tuyến thông điệp multicast. Ví dụ một vài trường hợp sử dụng:

  • Phân phối dữ liệu liên quan đến vị trí địa lý cụ thể.
  • Xử lý tác vụ nền được thực hiện bởi nhiều workers, mỗi công việc có khả năng xử lý các nhóm tác vụ cụ thể.
  • Cập nhật tin tức liên quan đến một category hoặc gắn tag.
  • Điều phối các dịch vụ của các loại khác nhau trong cloud.

Một topic exchange sẽ sử dụng wildcard để gắn routing key với một routing pattern khai báo trong binding. Consumer có thể đăng ký những topic mà nó quan tâm.

Ví dụ:

  • agreements.*.headstore : Được đăng ký bởi tất cả những key với pattern bắt đầu bằng agreements, theo sau là một từ bất kỳ và kết thúc là headstore.
  • agreements.# : Được đăng ký bởi tất cả các key bắt đầu với agreements.

Chi tiết về các wildcard tôi sẽ giới thiệu với các bạn ở một bài viết khác.

Headers Exchange

Header exchange được thiết kế để định tuyến với nhiều thuộc tính, để dàng thực hiện dưới dạng header của message hơn là routing key. Header exchange bỏ đi routing key mà thay vào đó định tuyến dựa trên header của message. Trường hợp này, broker cần một hoặc nhiều thông tin từ application developer, cụ thể là, nên quan tâm đến những tin nhắn với tiêu đề nào phù hợp hoặc tất cả chúng.

Headers Exchange rất giống với Topic Exchange, nhưng nó định tuyến dựa trên các giá trị header thay vì routing key.

Một Message được coi là phù hợp nếu giá trị của header bằng với giá trị được chỉ định khi ràng buộc.

Dead Letter Exchange

Nếu không tìm thấy hàng đợi phù hợp cho tin nhắn, tin nhắn sẽ tự động bị hủy. RabbitMQ cung cấp một tiện ích mở rộng AMQP được gọi là “Dead Letter Exchange”. Cung cấp chức năng để chụp các tin nhắn không thể gửi được.

Trên đây là những kiến thức cơ bản về RabbitMQ. Bài viết này hơi năng về lý thuyết, nhưng rất quan trọng để hiểu và dễ dàng làm việc với RabbitMQ sau này.

Tài liệu tham khảo:

  • https://www.rabbitmq.com/features.html
  • https://www.rabbitmq.com/tutorials/amqp-concepts.html
  • https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html
  • https://www.cloudamqp.com/blog/2015-09-03-part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html

 

5.0
22
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Message Queue Được gắn thẻ: JMS, Message Queue, RabbitMQ

Kết nối JMS Client với ActiveMQ
Cài đặt RabbitMQ

Có thể bạn muốn xem:

  • Sử dụng Dead Letter Exchange trong RabbitMQ (13/06/2020)
  • Sử dụng Direct Exchange trong RabbitMQ (26/05/2020)
  • Giới thiệu JMS – Java Message Services (30/04/2020)
  • Sử dụng binding Exchange to Exchange trong RabbitMQ (07/06/2020)
  • Sử dụng Headers Exchange trong RabbitMQ (04/06/2020)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97350 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (96986 lượt xem)
  • Giới thiệu Design Patterns (86648 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85483 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83024 lượt xem)

Nội dung bài viết

  • 1 RabbitMQ là gì?
  • 2 Tại sao sử dụng RabbitMQ?
  • 3 Những khái niệm cơ bản trong RabbitMQ
  • 4 RabbitMQ hoạt động như thế nào?
  • 5 Exchange và các loại Exchange

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link