路由模式—>direct
如果路由键完全匹配的话,消息才会被投放到相应的队列。
生产者代码:
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//所有的中间件技术都是基于tcp/ip协议基础之上构建新的协议规范,只不过rabbitmq遵循的是amqp
//1.创建连接工程
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("ip");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
Connection connection=null;
Channel channel =null;
try {
//创建连接Connection
connection = connectionFactory.newConnection("生产者");
//通过连接获取通道Channel
channel =connection.createChannel();
//创建交换机
String exchangeName = "direct_msg_exchange";
//设置交换机类型
String exchangeType ="direct";
//声明交换机 参数1:交换机名字 参数2:交换机类型 参数3:交换机是否持久化
channel.exchangeDeclare(exchangeName,exchangeType,true);
//声明队列名字
String queueName1= "queue1";
String queueName2= "queue2";
String queueName3= "queue3";
/*
*创建队列
*参数1: 队列名称 如果队列不存在自动创建
*参数2: 用来定义队列特性是否要持久化 true 持久化队列 false 不持久化(服务重启后
队列还保存,但不保存消息)
*参数3: exclusive 是否独占队列 true 独占队列 false 不独占
*参数4: autoDelete: 是否在消费完成后自动删除队列 true自动删除 false不自动删除
*参数5: 额外附加参数
*/
channel.queueDeclare(queueName1,true,false,false,null);
channel.queueDeclare(queueName2,true,false,false,null);
channel.queueDeclare(queueName3,true,false,false,null);
//绑定队列和交换机 参数1:队列名字 参数2:交换机名字 参数3:路由key
channel.queueBind(queueName1,exchangeName,"s1");
channel.queueBind(queueName2,exchangeName,"s2");
channel.queueBind(queueName3,exchangeName,"s1");
//准备消息内容
String message = "Hello RabbitMQ";
//发送消息给队列queue
channel.basicPublish(exchangeName,"s1",null,message.getBytes());
System.out.println("发送成功!");
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
//7.关闭连接
// if (channel!=null&&channel.isOpen()){
// channel.close();
// }
//8.关闭通道
// if (connection!=null&& connection.isOpen()){
// connection.close();
// }
}
}
}
成功运行生产者代码后,我们可以在RabbitMQ的图型管理页面发现增加了一个自定义的名为direct_msg_exchange交换机,查看该交换机,其类型为direct;并增加了三条队列,队列只有绑定routekey为s1的队列有一条信息。
查看交换机 发现新增自定义交换机:direct_msg_exchange
查看交换机信息,可以看到交换机类型为:direct
查看 队列,新增三条队列,绑定路由key为s1的队列1、3接收到消息
消费者代码:
public class Consumer {
public static Runnable runnable = new Runnable() {
@Override
public void run() {
//创建工厂
ConnectionFactory factory = new ConnectionFactory();
//连接
factory.setHost("120.77.69.225");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("admin");
factory.setPassword("admin");
//获取队列名称
final String queueName = Thread.currentThread().getName();
Connection connection = null;
Channel channel = null;
try {
//获取连接
connection = factory.newConnection("消费者");
//从连接中获取通道
channel = connection.createChannel();
//定义接收消息回调
channel.basicConsume(queueName, true, new DeliverCallback() {
@Override
public void handle(String s, Delivery delivery) throws IOException {
System.out.println(delivery.getEnvelope().getDeliveryTag());
System.out.println(queueName + ":收到消息:" + new String(delivery.getBody(), "UTF-8"));
}
}, new CancelCallback() {
@Override
public void handle(String s) throws IOException {
System.out.println("接收失败了。。。。");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
};
public static void main(String[] args) {
new Thread(runnable, "queue1").start();
new Thread(runnable, "queue2").start();
new Thread(runnable, "queue3").start();
}
}
成功运行消费者代码后,只有接收队列1、3的消费者得到了生产者的消息,在图形管理界面,可以发现队列里的消息已经被消费。