服务异步通信-Direct

发布于:2023-09-22 ⋅ 阅读:(53) ⋅ 点赞:(0)

请添加图片描述
个人名片:

博主酒徒ᝰ.
个人简介沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志三人行,必有我师焉。

请添加图片描述
本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 点击观看

三、SpringAMQP

4.发布、订阅模型-Direct

RabbitMQ是一种高效、可靠、灵活的消息队列中间件,用于实现分布式系统中的数据交换和消息处理。在RabbitMQ中,Direct模式是一种常见的消息路由模式,它实现了消息的点对点传递,确保每个消息只被一个消费者接收和处理。

一、RabbitMQ Direct模式概述
RabbitMQ的Direct模式是指消息按照一对一的原则进行路由,每个消息只有一个目标队列,同时只有一个消费者可以接收该消息。在Direct模式下,生产者将消息发送到特定的队列,然后由RabbitMQ根据需要将消息路由到一个或多个消费者。这种模式适用于需要对每个消息进行有序、可靠处理的场景。

二、RabbitMQ Direct模式工作原理

  • 消息路由

在Direct模式下,RabbitMQ会根据消息的属性将消息路由到一个特定的队列。消费者通过订阅该队列来接收和处理消息。当消费者成功处理消息后,RabbitMQ会从队列中删除该消息,使其无法被其他消费者接收。

  • 消息持久化

RabbitMQ的Direct模式支持消息的持久化存储,即消息可以保存在磁盘上,以防止在系统崩溃时丢失数据。此外,Direct模式还支持消息的内存缓存,以提高读取效率。

三、RabbitMQ Direct模式的优点

(1)一对一的消息传递:Direct模式实现了消息的一对一传递,避免了多个消费者之间的竞争和重复处理。
(2)可靠性高:由于每个消息只有一个目标消费者,因此可以确保每个消息只被一个消费者正确处理,提高了系统的可靠性。
(3)顺序性:Direct模式保证了消息按照发送顺序逐一被消费者接收和处理,适用于需要有序处理的情况。
(4)持久化存储:Direct模式支持消息的持久化存储,提高了系统的可靠性和稳定性。

四、RabbitMQ Direct模式的缺点

(1)负载均衡:由于每个消息只被一个消费者接收和处理,因此无法实现消息的负载均衡,限制了系统的吞吐量。
(2)消费者数量限制:每个队列只允许一个消费者接收消息,限制了可同时处理的消费者数量。

五、RabbitMQ Direct模式应用场景

  • 任务队列:在任务队列场景中,生产者将任务发布到特定队列,然后由多个消费者并行处理队列中的任务。由于每个任务只被一个消费者处理,因此可以保证任务的可靠性和完整性。
  • 点对点通信:在点对点通信场景中,RabbitMQ的Direct模式可以实现消息的可靠传递和有序处理。例如,在聊天应用中,Direct模式可以确保每条消息只能被一个用户接收,避免了消息的重复和竞争。
  • 事务处理:在事务处理场景中,需要保证每笔交易的原子性和一致性。Direct模式可以实现一对一的消息传递,确保每个事务只被一个节点处理,从而提高了事务处理的一致性和可靠性。
  • 订单处理:在订单处理场景中,每个订单都需要被单独处理,并保证处理的顺序和可靠性。Direct模式可以实现订单消息的一对一传递,确保每个订单只被一个处理器正确处理。

总结

RabbitMQ的Direct模式是一种简单、可靠的消息路由模式,适用于需要对每个消息进行有序、可靠处理的场景。它实现了消息的一对一传递,保证了每个消息只被一个消费者正确处理。然而,Direct模式也存在负载均衡和消费者数量限制等缺点。在应用中需要根据实际需求进行选择和优化。

发布订阅-DirectExchange

Direct Exchange 会将接收到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)。

每一个Queue都与Exchange设置一个BindingKey
发布者发送消息时,指定消息的RoutingKey
Exchange将消息路由到BindingKey与消息RoutingKey一致的队列

案例:利用SpringAMQP演示DirectExchange的使用

实现思路如下:
利用@RabbitListener声明Exchange、Queue、RoutingKey
在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2
在publisher中编写测试方法,向itcast. direct发送消息

步骤1:在consumer服务声明Exchange、Queue
在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2,
并利用@RabbitListener声明Exchange、Queue、RoutingKey

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "direct.queue1"),
        exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
        key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
    System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
}

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "direct.queue2"),
        exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
        key = {"red", "yello"}
))
public void listenDirectQueue2(String msg){
    System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
}

步骤2:在publisher服务发送消息到DirectExchange
在publisher服务的SpringAmqpTest类中添加测试方法:

@Test
public void testDirectExchange() {
    String exchangeName = "itcast.direct";
    String message = "hello, direct";
    rabbitTemplate.convertAndSend(exchangeName, "yello", message);
}

在这里插入图片描述

总结:

  1. 描述下Direct交换机与Fanout交换机的差异?
    Fanout交换机将消息路由给每一个与之绑定的队列
    Direct交换机根据RoutingKey判断路由给哪个队列
    如果多个队列具有相同的RoutingKey,则与Fanout功能类似
  2. 基于@RabbitListener注解声明队列和交换机有哪些常见注解?
    @Queue
    @Exchange
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到