一、交换机的属性
Name:交换机的名称
Type:交换机的类型,direct,topic,fanout,headers
Durability:是否需要持久化
autodelete:假如没有队列绑定到该交换机,那么该交换机会自动删除
Internal:当前交换机是否用户rabbitmq内部使用不常用,默认为false
Argurements:扩展参数,用户扩展AMQP 定制化协议
二、交换机的类型
2.1 直接交换机 direct exchange
所有发送到direct exchange的消息都会被投递到route key名称和queue名称相同的queue上
举个栗子
public class DirectExchangeProductor {
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//定义交换机名称
String exchangeName = "testDirect1";
//定义routingKey
String routingKey = "testExchange1.queue1";
//消息体内容
String messageBody = "hello world ";
channel.basicPublish(exchangeName,routingKey,null,messageBody.getBytes());
}
}
public class DirectExchangeConsumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
String exchangeName = "testDirect1";
String exchangeType = "direct";
String queueName = "testQueue1";
String routingKey = "testExchange1.queue1";
/**
* 声明一个交换机
* exchange:交换机的名称
* type:交换机的类型 常见的有direct,fanout,topic等
* durable:设置是否持久化。durable设置为true时表示持久化,反之非持久化.持久化可以将交换器存入磁盘,在服务器重启的时候不会丢失相关信息
* autodelete:设置是否自动删除。autoDelete设置为true时,则表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后,所有与这个交换器绑定的队列或者交换器都与此解绑。
* 不能错误的理解—当与此交换器连接的客户端都断开连接时,RabbitMq会自动删除本交换器
* arguments:其它一些结构化的参数,比如:alternate-exchange
*/
channel.exchangeDeclare(exchangeName,exchangeType,true,false,null);
/**
* 声明一个队列
* durable:表示rabbitmq关闭删除队列
* autodelete:表示没有程序和队列建立连接 那么就会自动删除队列
*
*/
channel.queueDeclare(queueName,true,false,false,null);
/**
* 队列和交换机绑定
*/
channel.queueBind(queueName,exchangeName,routingKey);
/**
* 创建一个消费者
*/
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
/**
* 开始消费
*/
channel.basicConsume(queueName,true,queueingConsumer);
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String reciverMessage = new String(delivery.getBody());
System.out.println("消费消息:-----"+reciverMessage);
}
}
}
2.2 主题交换机 TopicExchange
就是在队列上绑到交换机上的路由key 可以是通过通配符来匹配的。
通配符的规则是:
log.# :可以匹配一个单词,也可以匹配多个单词。比如log.#可以匹配log.a、log.b、log.a.b
log.* : 可以匹配一个单词。比如 log.* 可以匹配log.a但是不可以匹配log.a.b
举个栗子
public class TopicExchangeProductor {
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//发送消息
String exchangeName = "testDirect1";
String routingKey1 = "testExchange1.queue1.queue1";
String routingKey2 = "testExchange1.queue2";
String routingKey3 = "testExchange1.queue3";
channel.basicPublish(exchangeName,routingKey1,null,"我是第一条消息".getBytes());
channel.basicPublish(exchangeName,routingKey2,null,"我是第二条消息".getBytes());
channel.basicPublish(exchangeName,routingKey3,null,"我是第三条消息".getBytes());
}
}
public class TopicExchangeConsumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//声明交换机
String exchangeName = "testDirect1";
String exchangeType = "topic";
channel.exchangeDeclare(exchangeName,exchangeType,true,true,null);
//声明队列
String quequName = "testQueue1";
channel.queueDeclare(quequName,true,false,false,null);
//声明绑定关系
String bingdingStr = "testExchange1.*";
channel.queueBind(quequName,exchangeName,bingdingStr);
//声明一个消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//开始消费
/**
* 开始消费
*/
channel.basicConsume(quequName,true,queueingConsumer);
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
System.out.println("接受到消息:"+new String(delivery.getBody()));
}
}
}
执行结果
2.3 扇形交换机(fanout exchange)
就是消息通过从交换机到队列上不会通过路由key ,所以该模式的速度是最快的,只要和交换机绑定,那么消息就会
被分发到与之绑定的队列上
举个栗子
public class FanoutExchangeProductor {
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//定义交换机名称
String exchangeName = "testDirect2";
//定义routingKey
String routingKey = "";
//消息体内容
String messageBody = "hello world ";
channel.basicPublish(exchangeName,"123",null,"我是第一条消息".getBytes());
channel.basicPublish(exchangeName,"456",null,"我是第二条消息".getBytes());
channel.basicPublish(exchangeName,"789",null,"我是第三条消息".getBytes());
}
}
public class FanoutExchangeConsumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("10.101.102.167");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("test_vm1");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//声明交换机
String exchangeName = "testDirect2";
String exchangeType = "fanout";
channel.exchangeDeclare(exchangeName,exchangeType,true,true,null);
//声明队列
String quequName = "testQueue2";
channel.queueDeclare(quequName,true,false,false,null);
//声明绑定关系
String bingdingStr = "不需要绑定关系";
channel.queueBind(quequName,exchangeName,bingdingStr);
//声明一个消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//开始消费
channel.basicConsume(quequName,true,queueingConsumer);
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
System.out.println("接受到消息:"+new String(delivery.getBody()));
}
}
}