RabbitMQ---订阅模型-Direct

1、 订阅模型-Direct

• 有选择性的接收消息

• 在订阅模式中,生产者发布消息,所有消费者都可以获取所有消息。

• 在路由模式中,我们将添加一个功能 - 我们将只能订阅一部分消息。

例如,我们只能将重要的错误消息引导到日志文件(以节省磁盘空间),同时仍然能够在控制台上打印所有日志消息。

• 但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。

• 在Direct模型下,队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)

• 消息的发送方在向Exchange发送消息时,也必须指定消息的routing key。

• P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

• X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列

• C1:消费者,其所在队列指定了需要routing key 为 error 的消息

• C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息

1.1、生产者

此处我们模拟商品的增删改,发送消息的RoutingKey分别是:insert、update、delete

java 复制代码
public class Send {
   private final static String EXCHANGE_NAME = "direct_exchange_test";
   public static void main(String[] argv) throws Exception {
       // 获取到连接
       Connection connection = ConnectionUtil.getConnection();
       // 获取通道
       Channel channel = connection.createChannel();
       // 声明exchange,指定类型为direct
       channel.exchangeDeclare(EXCHANGE_NAME, "direct");
       // 消息内容
       String message = "商品新增了, id = 1001";
       // 发送消息,并且指定routing key 为:insert ,代表新增商品
       channel.basicPublish(EXCHANGE_NAME, "insert", null, message.getBytes());
       System.out.println(" [商品服务:] Sent '" + message + "'");
       channel.close();
       connection.close();
   }
}

1.2、消费者1

我们此处假设消费者1只接收两种类型的消息:更新商品和删除商品。

java 复制代码
public class Recv {
   private final static String QUEUE_NAME = "direct_exchange_queue_1";
   private final static String EXCHANGE_NAME = "direct_exchange_test";
   public static void main(String[] argv) throws Exception {
       // 获取到连接
       Connection connection = ConnectionUtil.getConnection();
       // 获取通道
       Channel channel = connection.createChannel();
       // 声明队列
       channel.queueDeclare(QUEUE_NAME, false, false, false, null);
       // 绑定队列到交换机,同时指定需要订阅的routing key。假设此处需要update和delete消息
       channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");
       channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "delete");
       // 定义队列的消费者
       DefaultConsumer consumer = new DefaultConsumer(channel) {
           // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
                   byte[] body) throws IOException {
               // body 即消息体
               String msg = new String(body);
               System.out.println(" [消费者1] received : " + msg + "!");
           }
       };
       // 监听队列,自动ACK
       channel.basicConsume(QUEUE_NAME, true, consumer);
   }
}

1.3、 消费者2

我们此处假设消费者2接收所有类型的消息:新增商品,更新商品和删除商品。

java 复制代码
public class Recv2 {
   private final static String QUEUE_NAME = "direct_exchange_queue_2";
   private final static String EXCHANGE_NAME = "direct_exchange_test";
   public static void main(String[] argv) throws Exception {
       // 获取到连接
       Connection connection = ConnectionUtil.getConnection();
       // 获取通道
       Channel channel = connection.createChannel();
       // 声明队列
       channel.queueDeclare(QUEUE_NAME, false, false, false, null);
       // 绑定队列到交换机,同时指定需要订阅的routing key。订阅 insert、update、delete
       channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "insert");
       channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");
       channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "delete");
       // 定义队列的消费者
       DefaultConsumer consumer = new DefaultConsumer(channel) {
           // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
                   byte[] body) throws IOException {
               // body 即消息体
               String msg = new String(body);
               System.out.println(" [消费者2] received : " + msg + "!");
           }
       };
       // 监听队列,自动ACK
       channel.basicConsume(QUEUE_NAME, true, consumer);
   }
}

1.4、测试

我们分别发送增、删、改的RoutingKey,发现结果:

相关推荐
咖啡啡不加糖15 小时前
Grafana 监控服务指标使用指南:打造可视化监控体系
java·后端·grafana
星期五不见面15 小时前
jetson naon super使用 sudo /opt/nvidia/jetson-io/jetson-io.py 界面闪退
linux·运维·服务器
gAlAxy...15 小时前
SpringBoot Servlet 容器全解析:嵌入式配置与外置容器部署
spring boot·后端·servlet
坐怀不乱杯魂15 小时前
Linux网络 - HTTPS
服务器·网络·网络协议·http·https
B2_Proxy15 小时前
亚马逊采集的正确打开方式:从合规边界到反爬博弈,再到数据价值落地
服务器·网络·网络协议·tcp/ip·chatgpt
网硕互联的小客服15 小时前
linux服务器忘记远程端口怎么办?如何找回?
linux·运维·服务器
历程里程碑15 小时前
Linux 16 环境变量
linux·运维·服务器·开发语言·数据库·c++·笔记
ZeroNews内网穿透15 小时前
关于飞牛fnOS重要安全更新的提醒
运维·服务器·web安全·ssh
BYSJMG15 小时前
计算机毕业设计选题推荐:基于Hadoop的城市交通数据可视化系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
BYSJMG16 小时前
Python毕业设计选题推荐:基于大数据的美食数据分析与可视化系统实战
大数据·vue.js·后端·python·数据分析·课程设计·美食