Master RabbitMQ: Core Concepts, Exchange Types, and Spring Boot Integration
This guide explains RabbitMQ fundamentals, its core components and four exchange types, and provides step‑by‑step Spring Boot examples—including configuration, code snippets, and testing procedures—to help developers effectively use fanout, headers, direct, and topic exchanges.
Environment
Spring Boot 2.3.10, RabbitMQ 3.8.12, Erlang 23.2.5
1.1 RabbitMQ Introduction
RabbitMQ is an open‑source message broker that implements the Advanced Message Queuing Protocol (AMQP). It is written in Erlang and provides client libraries for most major programming languages.
1.2 Core Concepts
Server (Broker) : Accepts client connections and provides AMQP services.
Connection : Network link between an application and the broker.
Channel : Logical communication path; all operations occur on a channel. A single TCP connection can host multiple channels.
Virtual Host : Logical isolation layer that contains exchanges and queues.
Binding : Virtual relationship between an exchange and a queue.
Routing key : Rule used by the broker to route a message; supports pattern matching with * (single word) and # (zero or more words) for topic exchanges.
Queue : Stores messages and forwards them to consumers.
Message : Data transferred between server and applications, consisting of properties (e.g., priority, TTL) and a body.
Exchange Types : fanout, headers, direct, topic.
1.3 Exchange Types
fanout : Broadcasts messages to all bound queues, ignoring routing keys.
headers : Routes based on message header values; rarely used.
direct : Routes messages whose routing key exactly matches the binding key.
topic : Routes using pattern matching with * and # in the routing key.
1.4 Usage Example
Dependencies
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency></code>Configuration (application.yml)
<code>spring:
rabbitmq:
host: localhost
port: 5672
username: admin
password: 123456
virtual-host: /
publisherConfirmType: correlated
publisherReturns: true
listener:
simple:
concurrency: 5
maxConcurrency: 10
prefetch: 5
acknowledgeMode: MANUAL
retry:
enabled: true
initialInterval: 3000
maxAttempts: 3
defaultRequeueRejected: false</code>fanout Exchange
Create a fanout exchange named fanout-exchange and three queues fanout-queue1 , fanout-queue2 , fanout-queue3 . Bind each queue to the exchange (routing key is ignored).
Test controller:
<code>@RestController
@RequestMapping("/messages")
public class MessageController {
@Resource
private MessageSend ms;
@GetMapping("/sendFanout")
public Object send(String msg) {
ms.send(msg);
return "success";
}
}
@Resource
private RabbitTemplate rabbitTemplate;
public void send(String msg) {
logger.info("准备发送消息:{}", msg);
rabbitTemplate.convertAndSend("fanout-exchange", "rk.1.2", msg);
}</code>All three queues receive the message, confirming that fanout exchanges ignore routing keys.
headers Exchange
Create a headers exchange headers-exchange and two queues headers-queue1 , headers-queue2 . Bind with header arguments (e.g., a=b , pack=xg ) and optionally x-match set to any or all .
Test controller:
<code>@GetMapping("/sendHeaders")
public Object sendHeaders(String msg) {
ms.sendHeaders(msg);
return "success";
}
public void sendHeaders(String msg) {
logger.info("准备发送消息:{}", msg);
Message message = MessageBuilder.withBody(msg.getBytes())
.setHeader("a", "b")
.setHeader("pack", "xg")
.build();
rabbitTemplate.send("headers-exchange", "rk.1.2", message);
}</code>When x-match=all , only headers-queue1 receives the message; after changing both bindings to x-match:any , both queues receive it.
direct Exchange
Create a direct exchange direct-exchange and two queues direct-queue1 , direct-queue2 . Bind each queue with a specific routing key.
Test controller:
<code>@GetMapping("/sendDirect")
public Object sendDirect(String msg) {
ms.sendDirect(msg);
return "success";
}
public void sendDirect(String msg) {
logger.info("准备发送消息:{}", msg);
rabbitTemplate.convertAndSend("direct-exchange", "de.m", msg);
}</code>Both queues receive the message because the routing key matches the binding keys.
topic Exchange
Create a topic exchange topic-exchange and two queues topic-queue1 , topic-queue2 . Bind with patterns such as te.*.ok and te.# .
Test controller:
<code>@GetMapping("/sendTopic")
public Object sendTopic(String msg) {
ms.sendTopic(msg);
return "success";
}
public void sendTopic(String msg) {
logger.info("准备发送消息:{}", msg);
rabbitTemplate.convertAndSend("topic-exchange", "te.1.ok", msg);
}</code>Both queues receive the message. Changing the routing key to te.2.ok results in only topic-queue2 receiving the message because its binding pattern te.# matches multiple words.
Conclusion
The article has demonstrated the four RabbitMQ exchange types—fanout, headers, direct, and topic—through Spring Boot configuration and RESTful test endpoints, illustrating how routing keys and header bindings affect message delivery.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.