接上一篇路由模式的学习,对最后一句话,不太确定,自己进行了测试,如下
测试非指定的routingkey
消费者绑定交换机时,指定错误的routingkey
//生产者:
//队列绑定交换机
channel.queueBind(DIRECT_QUEUE_INSERT, DIRECT_EXCHANGE, "insert");
channel.queueBind(DIRECT_QUEUE_UPDATE, DIRECT_EXCHANGE, "update");
//测试消费者
//队列绑定交换机
channel.queueBind(DIRECT_QUEUE_INSERT,DIRECT_EXCHANGE,"test");
启动上述的生产者
查看web管理页面
发送了一条新增的消息,未被消费
启动测试消费者
import com.ql.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
import static com.ql.routing.ProducerDemo.DIRECT_EXCHANGE;
import static com.ql.routing.ProducerDemo.DIRECT_QUEUE_INSERT;
/**
* @Description: TODO
* @author: qinlei
* @date: 2020年05月13日 15:09
*/
public class ConsumerTestDemo {
public static void main(String[] args) {
try {
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//声明交换机 路由模式的
channel.exchangeDeclare(DIRECT_EXCHANGE,BuiltinExchangeType.DIRECT);
//创建队列
channel.queueDeclare(DIRECT_EXCHANGE,true,false,false,null);
//队列绑定交换机
channel.queueBind(DIRECT_QUEUE_INSERT,DIRECT_EXCHANGE,"test");
//监听消息
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
/*
consumerTag消息者标签 在channel.basicConsume时候可以指定
envelope消息内容 可从中获取消息id,消息routingkey 交换机 消息和重转标记(收到消息失败后是否需要重新发送)
properties 消息属性
body 消息体
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println(consumerTag);
System.out.println(envelope.toString());
System.out.println(properties.toString());
System.out.println("新增--消费者:=====消息内容:" + new String(body));
}
};
/*
监听消息
参数一:队列名称
参数二:是否自动确认 设置为true表示消息接收到自动向mq回复接收到了
*/
channel.basicConsume(DIRECT_QUEUE_INSERT,true,defaultConsumer);
}catch (Exception e){}
}
}
该测试用例仅修改了绑定交换机时的路由key 且该key生产者中没有
启动后的控制台结果:
此时:web管理页面中的消息确实被消费了
指定空的routingkey
//测试消费者
//队列绑定交换机
channel.queueBind(DIRECT_QUEUE_INSERT,DIRECT_EXCHANGE,"");
生产者不变
启动消费者,启动生产者
依然可被消费
我惊了!
不是说好的接收不到吗?!
解决!!
昨晚又对rabbitmq的流程好好学习了下.
路由模式与之前的工作队列及简单队列的不同在于生产者发送消息时,是发送给交换机而不是对列
而我在写demo时,在生产者中绑定了队列,
这样的话,消息不经过交换机直接到达队列.所以routingKey就无意义!
根本就不经过他的匹配!!
所以会出现如题的情况
正确的生产者应该是:
import com.ql.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* @Description: TODO
* @author: qinlei
* @date: 2020年05月07日 9:59
*/
public class ProducerDemo {
static final String DIRECT_EXCHANGE = "direct_exchange";
static final String DIRECT_QUEUE_INSERT = "direct_queue_insert";
static final String DIRECT_QUEUE_UPDATE = "direct_queue_update";
public static void main(String[] args) {
try {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
/*
生命交换机 之前的消息直接发送至queue 发布与订阅模式 是先发送到交换机
参数1:交换机名称
参数2:交换机类型: fanout topic direct headers
*/
channel.exchangeDeclare(DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT);
/*##################################################################
########### 因为不是向队列发送,所以不需要创建队列,也不需要针对队列绑定交换机##
####################################################################
*/
//创建队列 不需要创建队列
/*
参数一:队列名称
参数二:是否持久化队列
参数三:是否独占本次连接
参数四:是否在不使用的时候自动删除队列
参数五:队列其他参数
*/
// channel.queueDeclare(DIRECT_QUEUE_INSERT, true, false, false, null);
//队列绑定交换机 不需要绑定
// channel.queueBind("", DIRECT_EXCHANGE, "update");
//要发送的消息 新增
String msg = "这是一条修改消息---路由模式";
//发送至交换机 指定路由名称为 insert
channel.basicPublish(DIRECT_EXCHANGE, "update", null, msg.getBytes());
System.out.println("修改消息已发送----路由模式");
channel.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里也对之前学习文章的路由模式DEMO代码进行修改…