概述
所谓RabbitMq中路由模式(Routing)为我们在将发送消息队列以及接收消息队列(queue)绑定到交换机(exchange)时指定了一个RoutingKey。然后我们在通过连接信道向交换机发送消息时指定一个RoutingKey,交换机会将该消息发送到routingKey对应的接收队列上。在Routing模式中我们使用的交换机类型为direct。
代码示例:
生产者代码,主要步骤:
- 获取连接(工具类部分代码查阅RabbitMQ(三) HelloWorld )
- 创建信道
- 声明交换机指定名称以及类型
- 声明消息队列
- 将不同消息队列绑定到交换机上并指定相应的路由key
- 发送消息,并指定交换机以及路由key
package com.xiaohui.rabbitmq.routing;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.xiaohui.rabbitmq.utils.ConnectionUtils;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer {
//交换机名称
public static final String DIRECT_EXCHANGE = "direct_exchange";
//队列1
public static final String DIRECT_QUEUE_1 = "delete_direct_queue_1";
//队列2
public static final String DIRECT_QUEUE_2 = "update_direct_queue_2";
public static void main(String[] args) throws IOException, TimeoutException {
//获取连接
Connection connection = ConnectionUtils.getConnection();
//创建信道
Channel channel = connection.createChannel();
//声明交换机
/**
* 参数一:交换机名称
* 参数二:交换机类型:fanout \topic \direct
*/
channel.exchangeDeclare(Producer.DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT);
/**
* 声明队列
* durabe:持久化的消息,mq重启后消息仍在。
* exclusive :独占的,一个消息队列独占一个连接
*/
channel.queueDeclare(Producer.DIRECT_QUEUE_1,true,false,false,null);
channel.queueDeclare(Producer.DIRECT_QUEUE_2,true,false,false,null);
//队列绑定交换机
channel.queueBind(Producer.DIRECT_QUEUE_1, Producer.DIRECT_EXCHANGE,"delete");
channel.queueBind(Producer.DIRECT_QUEUE_2, Producer.DIRECT_EXCHANGE,"update");
for (int i = 1; i < 6; i++) {
String msg = "路由模式小兔子来啦........"+i+"---"+(i%2 == 0 ? "delete":"update");
channel.basicPublish(Producer.DIRECT_EXCHANGE,(i%2 == 0 ? "delete":"update"),null,msg.getBytes());
System.out.println("已发送消息:"+msg);
}
channel.close();
connection.close();
}
}
消费端代码如下,主要步骤:
- 创建连接
- 创建信道
- 声明交换机 指定名称(必须和生产者声明的同一交换机)以及类型
- 声明消费队列
- 绑定队列到交换机,并指明路由key
- 创建一个消费者,并实现监听回调处理。
- 启动指定名称的消费者,并使用6步骤中生成的消费对象启动。
package com.xiaohui.rabbitmq.routing;
import com.rabbitmq.client.*;
import com.xiaohui.rabbitmq.utils.ConnectionUtils;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Cunsumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//创建消费端链接
Connection connection = ConnectionUtils.getConnection();
//创建消费端渠道
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(Producer.DIRECT_EXCHANGE,BuiltinExchangeType.DIRECT);
//声明消费队列
channel.queueDeclare(Producer.DIRECT_QUEUE_1, true,false,false,null);
//队列绑定到交换机
channel.queueBind(Producer.DIRECT_QUEUE_1,Producer.DIRECT_EXCHANGE,"delete");
//监听消息
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("==================路由消费者delete开始===================");
System.out.println("路由的key为:"+envelope.getRoutingKey());
System.out.println("交换机为:"+envelope.getExchange());
System.out.println("消息ID为:"+envelope.getDeliveryTag());
System.out.println("收到的消息为:"+new String(body,"UTF-8"));
System.out.println("===================路由消费者delete结束==================");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
/**
* 第二个参数表示是否 向mqserver自动回复收到
* 第三个参数表示消息回调
*/
channel.basicConsume(Producer.DIRECT_QUEUE_1,true,consumer);
}
}
消费者2代码:
package com.xiaohui.rabbitmq.routing;
import com.rabbitmq.client.*;
import com.xiaohui.rabbitmq.utils.ConnectionUtils;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Cunsumer2 {
public static void main(String[] args) throws IOException, TimeoutException {
//创建消费端链接
Connection connection = ConnectionUtils.getConnection();
//创建消费端渠道
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(Producer.DIRECT_EXCHANGE,BuiltinExchangeType.DIRECT);
//声明消费队列
channel.queueDeclare(Producer.DIRECT_QUEUE_2, true,false,false,null);
//队列绑定到交换机
channel.queueBind(Producer.DIRECT_QUEUE_2,Producer.DIRECT_EXCHANGE,"update");
//监听消息
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("==================路由消费者update开始===================");
System.out.println("路由的key为:"+envelope.getRoutingKey());
System.out.println("交换机为:"+envelope.getExchange());
System.out.println("消息ID为:"+envelope.getDeliveryTag());
System.out.println("收到的消息为:"+new String(body,"UTF-8"));
System.out.println("===================路由消费者update结束==================");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
/**
* 第二个参数表示是否 向mqserver自动回复收到
* 第三个参数表示消息回调
*/
channel.basicConsume(Producer.DIRECT_QUEUE_2,true,consumer);
}
}
运行效果:
消费者1:
==================路由消费者delete开始===================
路由的key为:delete
交换机为:direct_exchange
消息ID为:1
收到的消息为:路由模式小兔子来啦........2---delete
===================路由消费者delete结束==================
==================路由消费者delete开始===================
路由的key为:delete
交换机为:direct_exchange
消息ID为:2
收到的消息为:路由模式小兔子来啦........4---delete
===================路由消费者delete结束==================
消费者2打印:
==================路由消费者update开始===================
路由的key为:update
交换机为:direct_exchange
消息ID为:1
收到的消息为:路由模式小兔子来啦........1---update
===================路由消费者update结束==================
==================路由消费者update开始===================
路由的key为:update
交换机为:direct_exchange
消息ID为:2
收到的消息为:路由模式小兔子来啦........3---update
===================路由消费者update结束==================
==================路由消费者update开始===================
路由的key为:update
交换机为:direct_exchange
消息ID为:3
收到的消息为:路由模式小兔子来啦........5---update
===================路由消费者update结束==================