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 的使用的更多相关文章

  1. RabbitMQ系列(三)RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  2. 8、RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较 RabbitMQ中,除了Simple Queue和Work Queue之外的所有生产者提交的消息都由Exc ...

  3. 【转】RabbitMQ三种Exchange模式

    [转]RabbitMQ三种Exchange模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四 ...

  4. RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  5. RabbitMQ(三):消息持久化策略

    原文:RabbitMQ(三):消息持久化策略 一.前言 在正常的服务器运行过程中,时常会面临服务器宕机重启的情况,那么我们的消息此时会如何呢?很不幸的事情就是,我们的消息可能会消失,这肯定不是我们希望 ...

  6. RabbitMQ三种Exchange模式(fanout,direct,topic)的特性 -摘自网络

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  7. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  8. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较(转)

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  9. RabbitMQ三种Exchange模式

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

随机推荐

  1. JAVA记录-java代码优化策略

    java代码优化策略 1.生成对象时,合理分配空间和大小:new ArrayList(100); 2.优化for循环: Vector vect = new Vector(1000); For(int ...

  2. UVALive 4850 Installations 贪心

    题目链接  题意 工程师要安装n个服务,其中服务Ji需要si单位的安装时间,截止时间为di.超时会有惩罚值,若实际完成时间为ci,则惩罚值为max{0,ci-di}.从0时刻开始执行任务,问惩罚值最大 ...

  3. 服务器上的XML

    若想让浏览器能访问Web项目,需要配置服务器里的XML文件,XML文件是类似于HtML文件的纯文本文件,可以通过Web服务器轻松的存储和生成. XML可以通过ASP,PHP,数据库生成XML

  4. 05-迪米特法则(LOD 又名: 最少知道原则)

    1. 背景      类与类之间的关系越密切,耦合度越大,当一个类发生变化时,对另一个类的影响也越大. 2. 定义     一个类应该对其它类保持最少的了解. 3. 解决方法      尽量降低类与类 ...

  5. DOM盒子模型

    获取行间样式 style.height //获取行间样式高度 xx.currentStyle.height //计算后的样式高度 IE低版本 getComputedStyle().height //获 ...

  6. JS ——document、“或”、event(事件对象)

    1.document <document>是所以HTML的最高节点,比<html>的等级还要高. <document>的第一个子节点是“!”——document.c ...

  7. 标签页QTabWidget

    样式: import sys from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication, QWidget, QTab ...

  8. Web项目Shiro总结及源码(十六)

    shiro过虑器 过滤器简称 对应的java类 anon org.apache.shiro.web.filter.authc.AnonymousFilter authc org.apache.shir ...

  9. JS如何防止事件冒泡

    <div style="height:30px;line-height:30px;background:#FF0;text-align:center;" id="z ...

  10. MongoDB的基本概念

    MongoDB的基本概念 库 db就是数据库 文档就是数据表的行 集合就是数据表,这个没有模式,啥叫没有模式呢,就是没有列的定义,随便什么属性都行,这点就比关系行数据库牛逼10000000倍,逆天了.