RabbitMQ(三): exchange 的使用
1. Exchange(交换机)
生产者只能发送信息到交换机,交换机接收到生产者的信息,然后按照规则把它推送到对列中。
一方面是接收生产者的消息,另一方面是像队列推送消息。
匿名转发 ""
- fanout(不处理路由键)
// 声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); // 分发
// 发送消息
String msg = "hello ps.";
channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes());

- direct(处理路由键)

- topic exchange
将路由键和某模式匹配
# 匹配零个或者多个
* 匹配一个

2. 发布/订阅模式(publish/subscribe)
模型

解读:
一个消费者,多个生产者
每一个消费者都有自己的队列
生产者没有直接把消息发送到队列,而是发到了交换机
每个队列都要绑定到交换机上
生产者发送的消息经过交换机到达队列实现一个消息被多个消费者消费
生产者
public class Send {
private static final String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
// 声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); // 分发
// 发送消息
String msg = "hello ps.";
channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes());
System.out.println("Send: " + msg);
channel.close();
connection.close();
}
}

消息哪去了??丢失了!因为交换机没有存储的能力,在 rabbitmq 里面只有队列有存储能力。
因为这时候还没有队列绑定到这个交换机,所以数据丢失了。
消费者
- 消费者1
public class Recv1 {
public static final String QUEUE_NAME = "test_queue_fanout_email";
private static final String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 绑定队列到交换机(转发器)
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[1] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
- 消费者2(与消费者1类似)
public class Recv2 {
public static final String QUEUE_NAME = "test_queue_fanout_sms";
private static final String EXCHANGE_NAME = "test_exchange_fanout";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 绑定队列到交换机(转发器)
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[2] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}

3. 路由模式(Routing)
模型

生产者
public class Send {
private static final String EXCHANGE_NAME = "test_exchange_direct";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
// exchange
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String msg = "hello direct.";
String routingKey = "warning";
channel.basicPublish(EXCHANGE_NAME, routingKey, null, msg.getBytes());
System.out.println("send: " + msg);
channel.close();
connection.close();
}
}
消费者
- 消费者1
public class Recv1 {
private static final String EXCHANGE_NAME = "test_exchange_direct";
private static final String QUEUE_NAME = "test_queue_direct_1";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String routingKey = "error";
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, routingKey);
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[1] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
- 消费者2
public class Recv2 {
private static final String EXCHANGE_NAME = "test_exchange_direct";
private static final String QUEUE_NAME = "test_queue_direct_2";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String routingKey = "error";
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, routingKey);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "warning");
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[2] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
4. 主题模式(Topics)
模型

商品:发布、删除、修改、查询...
生产者
public class Send {
private static final String EXCHANGE_NAME = "test_exchange_topic";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
// exchange
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
String msg = "商品...";
channel.basicPublish(EXCHANGE_NAME, "goods.update", null, msg.getBytes());
System.out.println("send: " + msg);
channel.close();
connection.close();
}
}
消费者
- 消费者1
public class Recv1 {
private static final String EXCHANGE_NAME = "test_exchange_topic";
private static final String QUEUE_NAME = "test_queue_topic_1";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.add");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.update");
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[1] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
- 消费者2
public class Recv2 {
private static final String EXCHANGE_NAME = "test_exchange_topic";
private static final String QUEUE_NAME = "test_queue_topic_2";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.#");
channel.basicQos(1); // 保证一次只发送一个
// 定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
// 消息到达 触发方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[2] Recv msg: " + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done.");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false; // 自动应答 false
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
RabbitMQ(三): exchange 的使用的更多相关文章
- RabbitMQ系列(三)RabbitMQ交换器Exchange介绍与实践
RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...
- 8、RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较
RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较 RabbitMQ中,除了Simple Queue和Work Queue之外的所有生产者提交的消息都由Exc ...
- 【转】RabbitMQ三种Exchange模式
[转]RabbitMQ三种Exchange模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四 ...
- RabbitMQ交换器Exchange介绍与实践
RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...
- RabbitMQ(三):消息持久化策略
原文:RabbitMQ(三):消息持久化策略 一.前言 在正常的服务器运行过程中,时常会面临服务器宕机重启的情况,那么我们的消息此时会如何呢?很不幸的事情就是,我们的消息可能会消失,这肯定不是我们希望 ...
- RabbitMQ三种Exchange模式(fanout,direct,topic)的特性 -摘自网络
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较(转)
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
随机推荐
- Word不能添加目录?
我复制粘贴了一大把文字,标题也设置了,就是添加不了目录,也不知道是什么原因. 后来同事给我指点了一下,真是万分感激啊 比如下面这张图,第13章那么大的标题在那里,但是就是添加不了目录 原因是在于换行的 ...
- vue切换路由页面内容没有重载
项目中遇到这样一个问题: 在一个地方填了一个申请的表单,需要在另一个页面的列表上显示出来这条申请的数据,但是由于vue的缓存,在切换路由时列表上并没有及时更新数据,解决方法如下: vue路由切换时页面 ...
- POJ - 1019 Number Sequence (思维)
https://vjudge.net/problem/POJ-1019 题意 给一串1 12 123 1234 12345 123456 1234567 12345678 123456789 1234 ...
- Codeforces 590D Top Secret Task
D. Top Secret Task time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
- 第16月第23天 atos
1. grep --after-context=2 "Binary Images:" *crash xcrun atos -o zhiniao_adhoc_stg1.app.dSY ...
- 信息收集之censys
一.摘要 Censys提供了search.view.report.query.export以及data六种API接口. search接口的请求地址是https://www.censys.io/api/ ...
- G - Preparing for Exams
题目链接: https://vjudge.net/contest/251958#problem/G 具体思路: 圆内四边形内角互补,所以,如图所示. 证明,三角形oda和三角形obc相似. 第一步,角 ...
- Android常用网络请求框架Volley Retrofit (okHttp)
Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient.在 Android 5.0 的时候 Google 就不推荐使用 HttpClient ...
- Bootstrap 时间控件datetimepicker与timepicker
一.datetimepicker 首先,我们看看点击选择时间的时候的展示页面吧 年 月 ...
- CentOS和RedHat Linux的区别
RHEL 在发行的时候,有两种方式.一种是二进制的发行方式,另外一种是源代码的发行方式. 无论是哪一种发行方式,你都可以免费获得(例如从网上下载),并再次发布.但如果你使用了他们的在线升级(包括补丁) ...