Routing路由模式:

上图中各个模块的名称和作用:
1. P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。
2. X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列
3. C1:消费者,其所在队列指定了需要routing key 为 error 的消息
4. C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息
路由模式特点:
1. 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
2. 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey。
3. Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息
4. 且交换机的类型为:Direct/Topic,反正不能说广播类型了
生产者
public class Producer {
//Publish/Subscribe发布与订阅模式 的区别是交换机的类型为:Direct,还有队列绑定交换机的时候需要指定routing key。
public static void main(String[] args) throws IOException, TimeoutException {
//1. 创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2. 设置参数
connectionFactory.setHost("localhost");//ip 默认值 localhost
connectionFactory.setPort(5672);//端口 默认值 5672
connectionFactory.setUsername("guest");//用户名 默认 guest
connectionFactory.setPassword("guest");//密码 默认值 guest
connectionFactory.setVirtualHost("/");//虚拟机 默认值
//3. 创建连接 Connection
Connection connection = connectionFactory.newConnection();
//4. 创建Channel
Channel channel = connection.createChannel();
// 创建交换机,并指定交换机的寻找方式,此处为直连。貌似广播不能设置路由
String exchangeName = "test_direct";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true,false, null);
// 创建队列
String queue1Name = "test_direct_queue1";
String queue2Name = "test_direct_queue2";
/**
* 参数1:队列名称
* 参数2:是否定义持久化队列
* 参数3:是否独占本次连接
* 参数4:是否在不使用的时候自动删除队列
* 参数5:队列其它参数
*/
channel.queueDeclare(queue1Name, true, false, false, null);
channel.queueDeclare(queue2Name, true, false, false, null);
// 队列绑定交换机(在我们设置路由的时候,队列虽然绑定了交换机,但仍要判断路由是否对应)
channel.queueBind(queue1Name, exchangeName, "error");// 队列1绑定error路由
channel.queueBind(queue2Name, exchangeName, "info");
channel.queueBind(queue2Name,exchangeName,"error");// 队列2绑定info error warning路有
channel.queueBind(queue2Name,exchangeName,"warning");
String message = "日志信息:张三调用了delete方法.错误了,日志级别error";
// 发送消息(发送消息只需要有消息体,交换机,路由,队列就行了)
/**
* 参数1:交换机名称,如果没有指定则使用默认Default Exchage
* 参数2:路由key,简单模式可以传递队列名称
* 参数3:消息其它属性
* 参数4:消息内容
*/
//消息先经过交换机,交换机把信息交给对应路由的队列
channel.basicPublish(exchangeName, "info", null, message.getBytes());
//9. 释放资源
channel.close();
connection.close();
}
}
注意:多个消费者,每个消费者可能绑定的队列都不同,我们要注意,此处我们只举例出一个消费者。
消费者
public class Consumer1 {
//Publish/Subscribe发布与订阅模式 的区别是交换机的类型为:Direct,还有队列绑定交换机的时候需要指定routing key。
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2. 设置参数
connectionFactory.setHost("localhost");//ip 默认值 localhost
connectionFactory.setPort(5672);//端口 默认值 5672
connectionFactory.setUsername("guest");//用户名 默认 guest
connectionFactory.setPassword("guest");//密码 默认值 guest
connectionFactory.setVirtualHost("/");//虚拟机 默认值
//3. 创建连接 Connection
Connection connection = connectionFactory.newConnection();
//4. 创建Channel
Channel channel = connection.createChannel();
//5. 接收消息
String queue1Name = "test_direct_queue1";
String queue2Name = "test_direct_queue2";
Consumer consumer = new DefaultConsumer(channel){
/**
回调方法,当收到消息后,会自动执行该方法
1. consumerTag:标识
2. envelope:获取一些信息,交换机,路由key...
3. properties:配置信息
4. body:数据
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body:"+new String(body));
System.out.println("将日志信息打印到控制台.....");
}
};
//参数:1. queue:队列名称 2. autoAck:是否自动确认 3. callback:回调对象
channel.basicConsume(queue1Name,true, consumer);
}
}
266

被折叠的 条评论
为什么被折叠?



