一、依赖导入
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>
常用交换器
RabbitMQ常用的交换器类型有direct、topic、fanout种。
假设 有5个消息队列并且没有创建消费者 (方便结果演示)
扇形交换机 fanout
把消息发送给绑定了当前交换机的所有队列
public class ProducerFanout {
public static void main(String[] args) throws IOException, TimeoutException {
// 队列名
String queuename1="queue1";
String queuename2="queue2";
String queuename3="queue3";
String queuename4="queue4";
String queuename5="queue5";
// 交换机名
String exchangeName="fanoutDemo";
// 1. 连接rabbitmq
//配置连接信息 ip 端口 用户名 密码
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.145.128");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//开始连接
Connection connection = connectionFactory.newConnection();
// 2. 创建信道
Channel channel = connection.createChannel();
// 队列申报,如果先启动消费者,并且已经创建队列,则可以忽略队列的创建,否则由于没有队列导致报错
// 第一个参数表示队列名称、
// 第二个参数为是否持久化(true表示是,队列将在服务器重启时生存)、
// 第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除)、
// 第四个参数为当所有消费者客户端连接断开时是否自动删除队列、
// 第五个参数为队列的其他参数
channel.queueDeclare(queuename1,false,false,false,null);
channel.queueDeclare(queuename2,false,false,false,null);
channel.queueDeclare(queuename3,false,false,false,null);
channel.queueDeclare(queuename4,false,false,false,null);
channel.queueDeclare(queuename5,false,false,false,null);
// 3.创建交换机 通过通道创建交换机
//第一个参数:交换机名称
//第二个参数:交换机类型 扇形-fanout; 直连-direct; 主题-topic;
channel.exchangeDeclare(exchangeName, "fanout");
// 4.队列和交换机绑定
//第一个参数:队列名称
//第二个参数:交换机名称
//第三个参数:routing_key
channel.queueBind(queuename1,exchangeName,"");
channel.queueBind(queuename2,exchangeName,"");
channel.queueBind(queuename3,exchangeName,"");
channel.queueBind(queuename4,exchangeName,"");
channel.queueBind(queuename5,exchangeName,"");
// 5. 发送数据到交换机
// 发布消息
// 第一个参数为交换机名称、
// 第二个参数为队列的routing_key
// 第三个参数为消息的其他属性、
// 第四个参数为发送信息的主体 - 数据
channel.basicPublish(exchangeName,"",null,("hello,小毛鬼").getBytes());
// 6. 关闭资源
channel.close();
connection.close();
connectionFactory.clone();
}
}
结果:
总结:扇形交换机类似广播,就是绑定了在这个交换机的所有队列都会收到信息
直连交换机 direct
把消息发送给具体的队列
public class ProducerDirect {
public static void main(String[] args) throws IOException, TimeoutException {
// 队列名
String queuename1="queue1";
String queuename2="queue2";
String queuename3="queue3";
String queuename4="queue4";
String queuename5="queue5";
// 交换机名
String exchangeName="directDemo";
// 1. 连接rabbitmq
//配置连接信息 ip 端口 用户名 密码
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.145.128");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//开始连接
Connection connection = connectionFactory.newConnection();
// 2. 创建信道
Channel channel = connection.createChannel();
// 创建队列,如果先启动消费者,并且已经创建队列,则可以忽略队列的创建,否则报错
// 第一个参数表示队列名称、
// 第二个参数为是否持久化(true表示是,队列将在服务器重启时生存)、
// 第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除)、
// 第四个参数为当所有消费者客户端连接断开时是否自动删除队列、
// 第五个参数为队列的其他参数
channel.queueDeclare(queuename1,false,false,false,null);
channel.queueDeclare(queuename2,false,false,false,null);
channel.queueDeclare(queuename3,false,false,false,null);
channel.queueDeclare(queuename4,false,false,false,null);
channel.queueDeclare(queuename5,false,false,false,null);
// 3.创建交换器
//第一个参数:交换机名称
//第二个参数:交换机类型 扇形-fanout; 直连-direct; 主题-topic;
channel.exchangeDeclare(exchangeName, "direct");
// 4.队列和交换器绑定
//第一个参数:队列名称
//第二个参数:交换机名称
//第三个参数:设置队列的routing_key
channel.queueBind(queuename1,exchangeName,"1");
channel.queueBind(queuename2,exchangeName,"2");
channel.queueBind(queuename3,exchangeName,"3");
channel.queueBind(queuename4,exchangeName,"1");
channel.queueBind(queuename5,exchangeName,"2");
// 5. 发送数据
// 发布消息
// 第一个参数为交换机名称、
// 第二个参数为队列映射的路由 routing_key
// 第三个参数为消息的其他属性、
// 第四个参数为发送信息的主体 -数据
channel.basicPublish(exchangeName,"1",null,("hello,小毛鬼").getBytes());
// 6. 关闭资源
channel.close();
connection.close();
connectionFactory.clone();
}
}
结果:
总结:
- 第4步 队列和交换器绑定时,声明队列的routing_key
- 第5步 发送消息时需要指定routing_key,把信息具体发送到什么队列
主题交换机 topic
进行模糊匹配发送数据到队列中
“*” 可以替代一个单词。“#” 可以替换零个或多个单词。“.” 单词之间的分隔符
public class ProducerToppic {
public static void main(String[] args) throws IOException, TimeoutException {
// 队列名
String queuename1="queue1";
String queuename2="queue2";
String queuename3="queue3";
String queuename4="queue4";
String queuename5="queue5";
// 交换机名
String exchangeName="topicDemo";
// 1. 连接rabbitmq
//配置连接信息 ip 端口 用户名 密码
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.145.128");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//开始连接
Connection connection = connectionFactory.newConnection();
// 2. 创建通道(是有名字的)
Channel channel = connection.createChannel();
// 创建队列,如果先启动消费者,并且已经创建队列,则可以忽略队列的创建,否则报错
// 第一个参数表示队列名称、
// 第二个参数为是否持久化(true表示是,队列将在服务器重启时生存)、
// 第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除)、
// 第四个参数为当所有消费者客户端连接断开时是否自动删除队列、
// 第五个参数为队列的其他参数
channel.queueDeclare(queuename1,false,false,false,null);
channel.queueDeclare(queuename2,false,false,false,null);
channel.queueDeclare(queuename3,false,false,false,null);
channel.queueDeclare(queuename4,false,false,false,null);
channel.queueDeclare(queuename5,false,false,false,null);
// 3.创建交换机
//第一个参数:交换机名称
//第二个参数:交换机类型 扇形-fanout; 直连-direct; 主题-topic;
channel.exchangeDeclare(exchangeName, "topic");
// 4.队列和交换机绑定
//第一个参数:队列名称
//第二个参数:交换机名称
//第三个参数:设置队列的routing_key
channel.queueBind(queuename1,exchangeName,"fast.*.*");
channel.queueBind(queuename2,exchangeName,"*.*.white");
channel.queueBind(queuename3,exchangeName,"fast.#");
channel.queueBind(queuename4,exchangeName,"*.fast.#");
channel.queueBind(queuename5,exchangeName,"*.*.*.*");
// 5. 发送数据
// 发布消息
// 第一个参数为交换机名称、
// 第二个参数 自定义的routing_key,自动 匹配队列的routing_key,进行信息发布
// 第三个参数为消息的其他属性、
// 第四个参数为发送信息的主体 - 数据
channel.basicPublish(exchangeName,"fast.rabbit.white",null,("hello,小毛鬼").getBytes());
// 6. 关闭资源
channel.close();
connection.close();
connectionFactory.clone();
}
}
结果:
总结:
- 第4步 队列和交换器绑定时,声明队列的匹配规则
- 第5步 发送消息时需要指定具体routing_key,和自动和队列的routing_key 进行模糊匹配
- “*” 可以替代一个单词。“#” 可以替换零个或多个单词。“.” 单词之间的分隔符
具体图表示
扇形交换机:所有对于都能获取到数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jLnlt1N-1596175686013)(F:\学习总结\JavaEE总结篇\Rabbit MQ\rabbitmq\img\扇形交换器.png)]
直连交换机:匹配key,才能获取数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4u7RdHRW-1596175686015)(F:\学习总结\JavaEE总结篇\Rabbit MQ\rabbitmq\img\直连交换器.png)]
主题交换机:模糊匹配key ,才能获取数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vW56QLqL-1596175686017)(F:\学习总结\JavaEE总结篇\Rabbit MQ\rabbitmq\img\主题交换器.png)]
y,和自动和队列的routing_key 进行模糊匹配
3. “*” 可以替代一个单词。“#” 可以替换零个或多个单词。“.” 单词之间的分隔符
具体图表示
扇形交换机:所有对于都能获取到数据
直连交换机:匹配key,才能获取数据
主题交换机:模糊匹配key ,才能获取数据