Exchange交换机
Exchange:接收消息,并根据路由键转发消息锁绑定的队列
交换机属性
-
Type:direct、topic、 fanout、headers
-
Durability:是否需要持久化、true为持久化
-
Auto Delete:当最后一个绑定到Exchange上的队列删除后,自动删除该exchange
-
Internal: 当前exchange 是否用于RabbitMQ内部使用,默认是False
-
Arguments:扩展参数,用于扩展AMQP协议自制化使用
1.direct Exchange
- 所有发送到Direct exchange 的消息会被转发到RouteKey中指定的Queue
- 注意:Direct模式可以使用RabbitMQ自带的Excahnge:default
exchange,所以不需要将Exchange进行任何绑定操作,消息传递时,RouteKey必须完全匹配才会被队列接收,否则该消息会被抛弃。
package com.lin.directexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* @author LCW
* @since 2020/3/31 17:47
*/
public class Producer {
public static void main(String[] args) throws Exception {
//1.创建一个ConnectFactory,进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2.通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3.通过Connection创建一个Channel
Channel channel = connection.createChannel();
//4.声明
String exchangeName = "test_direct_exchange";
String routingKey = "test.direct";
//5.发送数据
String msg = "hello rabbitMQ! Direct exchange message....";
channel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
//6.关闭连接
channel.close();
connection.close();
}
}
package com.lin.directexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author LCW
* @since 2020/4/3 9:25
*/
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
connectionFactory.setAutomaticRecoveryEnabled(true);
connectionFactory.setNetworkRecoveryInterval(3000);
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//声明
String exchangeName = "test_direct_exchange";
String exchangeType = "direct";
String queueName = "test_direct_queue";
String routingKey = "test.direct";
//声明一个交换机
channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
//声明一个队列
channel.queueDeclare(queueName, false, false, false, null);
//建立一个绑定关系
channel.queueBind(queueName, exchangeName, routingKey);
//durable 是否持久化消息
QueueingConsumer consumer = new QueueingConsumer(channel);
//参数:队列名称,是否自动ACK,Consumer
channel.basicConsume(queueName, true, consumer);
while (true) {
//获取消息,如果没有消息,这一步将一直堵塞
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String mag = new String(delivery.getBody());
System.out.println("收到信息;" + mag);
}
}
}
2.Topic Exchange
-
所有发送到Topic Exchange 的消息被转发到所有关心RouteKey中指定Topic的Queue上 Exchange
-
将RouteKey和某Topic 进行模糊匹配,此时队列需要绑定一个Topic
-
注意:可以使用通配符进行模糊匹配 符号“#” 匹配一个或多个词 符号“*”匹配一个词
producer代码
package com.lin.topicexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* @author LCW
* @since 2020/3/31 17:47
*/
public class Producer {
public static void main(String[] args) throws Exception {
//1.创建一个ConnectFactory,进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2.通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3.通过Connection创建一个Channel
Channel channel = connection.createChannel();
//4.声明
String exchangeName = "test_topic_exchange";
String routingKey1 = "user.save";
String routingKey2 = "user.update";
String routingKey3 = "user.delete.abc";
//5.发送数据
String msg = "hello rabbitMQ! TOPIC exchange message....";
channel.basicPublish(exchangeName, routingKey1, null, msg.getBytes());
channel.basicPublish(exchangeName, routingKey2, null, msg.getBytes());
channel.basicPublish(exchangeName, routingKey3, null, msg.getBytes());
//6.关闭连接
channel.close();
connection.close();
}
}
Consumer 代码
package com.lin.topicexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author LCW
* @since 2020/4/3 9:25
*/
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
connectionFactory.setAutomaticRecoveryEnabled(true);
connectionFactory.setNetworkRecoveryInterval(3000);
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//声明
String exchangeName = "test_topic_exchange";
String exchangeType = "topic";
String queueName = "test_topic_queue";
String routingKey = "user.*";//*只能匹配一个单词
// String routingKey = "user.#";//可以匹配多个单词
//声明交换机
channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
//声明队列
channel.queueDeclare(queueName, false, false, false, null);
//建立一个绑定关系
channel.queueBind(queueName, exchangeName, routingKey);
//durable 是否持久化消息
QueueingConsumer consumer = new QueueingConsumer(channel);
//参数:队列名称,是否自动ACK,Consumer
channel.basicConsume(queueName, true, consumer);
while (true) {
//获取消息,如果没有消息,这一步将一直堵塞
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String mag = new String(delivery.getBody());
System.out.println("收到信息;" + mag);
}
}
}
3.Fanout Exchange
- 不处理路由键,只需要简单的将队列绑定到交换机上 发送到交换机的消息都会被转发到与该交换机绑定的所有的队列上
- Fanout 交换机转发消息是最快的
package com.lin.fanoutexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* @author LCW
* @since 2020/3/31 17:47
*/
public class Producer {
public static void main(String[] args) throws Exception {
//1.创建一个ConnectFactory,进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2.通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3.通过Connection创建一个Channel
Channel channel = connection.createChannel();
//4.声明
String exchangeName = "test_fanout_exchange";
//5.发送数据
for (int i = 0; i < 10; i++) {
String msg = "hello rabbitMQ! fanout exchange message....";
channel.basicPublish(exchangeName, "aaa", null, msg.getBytes());
}
//6.关闭连接
channel.close();
connection.close();
}
}
package com.lin.fanoutexchange;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author LCW
* @since 2020/4/3 9:25
*/
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("120.26.71.129");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
connectionFactory.setAutomaticRecoveryEnabled(true);
connectionFactory.setNetworkRecoveryInterval(3000);
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//声明
String exchangeName = "test_fanout_exchange";
String exchangeType = "fanout";
String queueName = "test_fanout_queue";
String routingKey = "";//不设置路由键
//声明交换机
channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
//声明队列
channel.queueDeclare(queueName, false, false, false, null);
//建立一个绑定关系
channel.queueBind(queueName, exchangeName, routingKey);
//durable 是否持久化消息
QueueingConsumer consumer = new QueueingConsumer(channel);
//参数:队列名称,是否自动ACK,Consumer
channel.basicConsume(queueName, true, consumer);
while (true) {
//获取消息,如果没有消息,这一步将一直堵塞
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String mag = new String(delivery.getBody());
System.out.println("收到信息;" + mag);
}
}
}