RabbitMQ是一个广泛使用的开源消息代理软件,它支持多种消息传递模式,每种模式都适用于不同的应用场景。以下是RabbitMQ支持的五种主要模式:
1. 简单模式(Simple Mode)
简单模式是最基本的消息传递模式,它涉及一个生产者和一个消费者。生产者将消息发送到队列,消费者从队列中接收并处理消息。这种模式适用于简单的点对点通信场景。
示例:
// 生产者
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
channel.queueDeclare("simple_queue", false, false, false, null);
channel.basicPublish("", "simple_queue", null, "Hello World!".getBytes());
}
// 消费者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received '" + message + "'");
};
channel.basicConsume("simple_queue", true, deliverCallback, consumerTag -> {});
}
2. 工作队列模式(Work Queue Mode)
工作队列模式允许多个消费者从同一个队列中接收消息。这种模式通过在消费者之间分配任务来提高消息处理的效率。RabbitMQ默认采用轮询的方式分发消息,确保每个消费者接收到的消息数量大致相同。
示例:
// 生产者代码同上
// 消费者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received '" + message + "'");
// 模拟处理时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
channel.basicConsume("work_queue", false, deliverCallback, consumerTag -> {});
}
3. 发布/订阅模式(Publish/Subscribe Mode)
发布/订阅模式允许生产者将消息发送到交换机(Exchange),交换机再将消息广播到所有绑定到它的队列。这种模式适用于需要将同一消息发送给多个消费者的场景。
示例:
// 生产者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
channel.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
channel.basicPublish("logs", "", null, "info: Hello World!".getBytes());
}
// 消费者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, "logs", "");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received '" + message + "'");
};
channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
}
4. 路由模式(Routing Mode)
路由模式允许生产者将消息发送到特定类型的交换机(Direct Exchange),并通过路由键(Routing Key)将消息路由到特定的队列。这种模式提供了更细粒度的消息传递控制。
示例:
// 生产者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
channel.exchangeDeclare("direct_logs", BuiltinExchangeType.DIRECT);
String severity = "error";
channel.basicPublish("direct_logs", severity, null, "error: Hello World!".getBytes());
}
// 消费者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
String queueName = channel.queueDeclare().getQueue();
String severity = "error";
channel.queueBind(queueName, "direct_logs", severity);
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received '" + message + "'");
};
channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
}
5. 主题模式(Topics Mode)
主题模式是路由模式的一种扩展,它使用通配符匹配路由键,允许更灵活的消息路由。这种模式适用于需要根据消息内容进行动态路由的场景。
示例:
// 生产者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
channel.exchangeDeclare("topic_logs", BuiltinExchangeType.TOPIC);
String routingKey = "kern.critical";
channel.basicPublish("topic_logs", routingKey, null, "kern critical: Hello World!".getBytes());
}
// 消费者
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
String queueName = channel.queueDeclare().getQueue();
String bindingKey = "kern.*";
channel.queueBind(queueName, "topic_logs", bindingKey);
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received '" + message + "'");
};
channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
}
通过上述五种模式,RabbitMQ提供了灵活的消息传递机制,可以满足各种复杂的应用需求。开发者可以根据具体的业务场景选择合适的模式来实现高效的消息通信。