当前位置:   article > 正文

actual combat 32 —— RabbitMQ

actual combat 32 —— RabbitMQ

1. 五种模式

RabbitMQ有五种工作模式,分别是简单模式、工作模式、发布订阅模式、路由模式和主题模式

  • 简单模式(Simple Mode):这种模式包含一个生产者和一个消费者。生产者将消息发送到队列,消费者从队列中获取消息。
  • 工作模式(Work Mode):在这种模式下,有一个生产者和多个消费者。生产者将消息发送到队列,多个消费者可以同时监听并消费队列中的消息,但每条消息只会被一个消费者消费。
  • 发布订阅模式(Publish/Subscribe Mode):在这种模式下,一个生产者发送的消息会被多个消费者获取。生产者将消息发送到交换机,交换机将消息发布到所有绑定的队列中,消费者从各自监听的队列中获取消息。
  • 路由模式(Routing Mode):生产者发送消息到交换机时,需要指定路由键。消费者将队列绑定到交换机时,也需要指定路由键。交换机根据消息的路由键和队列绑定的路由键进行匹配,将消息发送到匹配的队列中。
  • 主题模式(Topic Mode):主题模式与路由模式类似,但路由键是多级路径,可以使用通配符进行模糊匹配。交换机根据消息的路由键和队列绑定的路由键的匹配程度,将消息发送到匹配的队列中。

2. 四种交换机

  • 扇形交换机(Fanout Exchange):它是最基本的交换机类型,会将消息分别发送给所有绑定到扇形交换机上的消息队列。路由键在扇形交换机里没有作用,故消息队列绑定扇形交换机时,路由键可为空。
  • 直连交换机(Direct Exchange):直连交换机是一种带路由功能的交换机,它会将消息的Routing Key与队列绑定的Routing Key进行完全匹配,然后将消息路由到相应的队列。
  • 主题交换机(Topic Exchange):主题交换机根据消息的Routing Key和通配符模式进行匹配,将消息路由到一个或多个队列。例如,“#”匹配一个或者多个词,“*”匹配一个词。
  • 头部交换机(Headers Exchange):头部交换机根据消息的头部信息(Header)进行匹配,将消息路由到匹配的队列

3. 工作模式和交换机的关系

关于交换机的不同和工作模式的不同,它们之间的主要区别在于:

交换机:决定了消息的路由方式。不同类型的交换机提供了不同的消息分发机制,例如广播、路由、匹配等。
工作模式:定义了消息的生产和消费方式。不同的工作模式适用于不同的应用场景,例如简单模式适用于一对一的消息传递,而发布订阅模式适用于一对多的消息传递。
总的来说,RabbitMQ的交换机和工作模式共同构成了其强大的消息传递和处理能力,可以根据具体的应用需求进行选择和配置。

4. 扇出交换机会向不同的队列同时发送消息,它是把相同的消息发送到不同的队列,这样不会造成消息被重复消费的bug吗?

许多场景中,这是期望的行为,因为每个队列的消费者可能负责处理消息的某个特定方面或将其发送到不同的系统或服务。
例如,假设您有一个日志系统,您可能希望将每条日志消息都发送到多个队列中,以便进行不同的处理或存储。一个队列可能用于实时分析,另一个队列可能用于归档,还有一个队列可能用于警报系统。在这种情况下,您会期望每个消费者都从其队列中接收到所有日志消息,并相应地处理它们。
然而,如果在您的应用程序中,多个消费者处理相同的消息会导致问题(例如,重复处理或数据不一致),那么您就需要考虑使用其他类型的交换机(如直连交换机或主题交换机)以及路由键来更精细地控制消息的路由。
总之,扇出交换机的广播行为本身并不一定会导致bug,这取决于您的应用程序如何处理这些消息。在设计消息传递系统时,您应该仔细考虑您的需求,并选择最适合您场景的交换机类型和路由策略。

参考:https://blog.csdn.net/qq_45173404/article/details/121687489

5. 不同的模式分别应该使用什么交换机?

在RabbitMQ中,不同的消息传递模式确实与不同类型的交换机相匹配。以下是根据您提到的消息传递模式推荐的交换机类型:

(1)简单模式(Simple Mode):

  • Direct Exchange:在这种模式下,消息通过指定的路由键被路由到与之匹配的队列中。Direct Exchange是最简单的交换机类型,它实现了基于路由键的精确匹配。

(2)工作模式(Work Mode):

  • Direct Exchange:同样适用于工作模式。在这种模式下,消息被发送到同一个队列,由多个消费者共同处理。Direct Exchange确保消息按路由键发送到正确的队列。

(3)发布订阅模式(Publish/Subscribe):
(个人感觉:发布订阅模式使用的应该是扇出交换机,然后不指定路由键,如果使用主题交换机,就是主题模式了)

  • Fanout Exchange:在这种模式下,消息被广播到所有与该交换机绑定的队列中,而不管路由键是什么。
  • Topic Exchange:也适用于发布订阅模式,但提供了更灵活的路由规则。队列可以通过通配符绑定到交换机上,允许基于路由键模式的订阅。

(4)路由模式(Routing Mode):

  • Direct Exchange:在路由模式下,消息根据路由键被路由到不同的队列。Direct Exchange通过路由键的精确匹配来实现这一点。
  • Topic Exchange:同样适用于路由模式,但提供了基于通配符的路由规则,使得路由更加灵活。

(5)主题模式(Topic Mode):

  • Topic Exchange:主题模式实际上是发布订阅模式的一种特殊情况,它使用Topic Exchange来实现基于通配符的路由规则。消息根据路由键和通配符模式被路由到一个或多个匹配的队列中。

请注意,这些建议仅作为一般指导,具体选择哪种交换机类型还需要根据业务需求和场景来决定。在某些情况下,可能还需要结合使用多种交换机类型来实现复杂的消息路由和分发策略。同时,RabbitMQ还支持其他高级功能,如消息持久化、消息确认机制等,可以根据需要进行配置和使用。

6. rabbitmq中路由模式和主题模式有什么区别?整合springboot代码举例

在RabbitMQ中,路由模式(Routing)和主题模式(Topic)的主要区别在于它们使用的交换机类型(Exchange Type)和路由键(Routing Key)的匹配方式。

路由模式(Routing):

使用Direct Exchange。
消息通过路由键(Routing Key)与队列绑定键(Binding Key)的精确匹配进行路由。
如果路由键与绑定键完全匹配,消息才会被发送到相应的队列。

主题模式(Topic):

使用Topic Exchange。
消息通过路由键与队列绑定键的模式匹配进行路由。
绑定键和路由键可以包含.(点)和*(星号)以及#(井号)作为通配符。
*(星号)代表一个单词。
#(井号)代表零个或多个单词。
Spring Boot 代码示例
路由模式(Routing)

生产者(Sender)

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String exchange, String routingKey, String message) {
    rabbitTemplate.convertAndSend(exchange, routingKey, message);
}

// 使用示例
sendMessage("directExchange", "key1", "This is a routing message for key1.");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

消费者(Receiver)

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "queue1", durable = "true"),
        exchange = @Exchange(value = "directExchange", type = ExchangeTypes.DIRECT),
        key = "key1"
))
public void receiveMessage(String message) {
    System.out.println("Received Routing Message: " + message);
}

// 另一个消费者监听不同的路由键
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "queue2", durable = "true"),
        exchange = @Exchange(value = "directExchange", type = ExchangeTypes.DIRECT),
        key = "key2"
))
public void receiveMessage2(String message) {
    System.out.println("Received Routing Message for key2: " + message);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

主题模式(Topic)

生产者(Sender)

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String exchange, String routingKey, String message) {
    rabbitTemplate.convertAndSend(exchange, routingKey, message);
}

// 使用示例
sendMessage("topicExchange", "stock.usd.nyse", "This is a topic message for stock.usd.nyse.");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

消费者(Receiver)

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "topicQueue1", durable = "true"),
        exchange = @Exchange(value = "topicExchange", type = ExchangeTypes.TOPIC),
        key = "stock.*" // 匹配所有以 "stock." 开头的路由键
))
public void receiveMessage(String message) {
    System.out.println("Received Topic Message: " + message);
}

// 另一个消费者监听不同的模式
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "topicQueue2", durable = "true"),
        exchange = @Exchange(value = "topicExchange", type = ExchangeTypes.TOPIC),
        key = "*.nyse.#" // 匹配所有以 ".nyse." 结尾的路由键,以及包含 ".nyse." 的路由键
))
public void receiveMessage2(String message) {
    System.out.println("Received Topic Message for nyse: " + message);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在上面的示例中,生产者使用RabbitTemplate来发送消息,而消费者则通过@RabbitListener注解来监听队列并接收消息。注意在配置交换机和队列时指定了交换机类型和路由键或绑定键的模式。

7. 发布订阅模式、路由模式、主题模式有何区别

  • 发布订阅模式就是没有路由键,交换机和队列直接绑定,发送消息到对应的交换机,交换机直接转发到与它绑定的所有队列上。
  • 路由模式与发布订阅模式相比,就是多了一个路由键
  • 主题模式和路由模式相比就是路由键是支持模糊查询的
    RabbitMQ中的发布订阅模式(Publish/Subscribe)、路由模式(Routing)和主题模式(Topic)在消息传递时有着不同的特点和行为。以下是它们之间的主要区别,以及对应的代码示例。
  1. 发布订阅模式(Publish/Subscribe)

特点:

消息发送者(生产者)将消息发送到交换机(Exchange)。
交换机将消息发送到所有与之绑定的队列。
每个队列都可能有多个消费者。

代码示例(基于Spring AMQP):

生产者:

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String message) {
    rabbitTemplate.convertAndSend("fanoutExchange", "", message); // 发送消息到fanout类型的交换机,routingKey不需要
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

消费者(可以有多个):

@RabbitListener(queues = "queue1")
public void receiveMessage(String message) {
    System.out.println("Consumer 1 received: " + message);
}

@RabbitListener(queues = "queue2")
public void receiveAnotherMessage(String message) {
    System.out.println("Consumer 2 received: " + message);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 路由模式(Routing)

特点:

消息发送者将消息发送到交换机,并指定一个路由键(Routing Key)。
交换机根据路由键将消息发送到匹配的队列。
队列通过绑定键(Binding Key)与交换机绑定,并决定接收哪些路由键的消息。

代码示例:

生产者:

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String routingKey, String message) {
    rabbitTemplate.convertAndSend("directExchange", routingKey, message); // 发送消息到direct类型的交换机,并指定routingKey
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

消费者(可以有多个,每个消费者监听不同的路由键):

@RabbitListener(queues = "queueForRoutingKeyA")
public void receiveMessageA(String message) {
    System.out.println("Received message for routing key A: " + message);
}

@RabbitListener(queues = "queueForRoutingKeyB")
public void receiveMessageB(String message) {
    System.out.println("Received message for routing key B: " + message);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

队列绑定到交换机时的配置(Spring配置类):

@Bean
Binding bindingA(Queue queueForRoutingKeyA, DirectExchange directExchange) {
    return BindingBuilder.bind(queueForRoutingKeyA).to(directExchange).with("routingKeyA");
}

@Bean
Binding bindingB(Queue queueForRoutingKeyB, DirectExchange directExchange) {
    return BindingBuilder.bind(queueForRoutingKeyB).to(directExchange).with("routingKeyB");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 主题模式(Topic)

特点:

消息发送者将消息发送到交换机,并指定一个路由键。
交换机根据路由键和队列的绑定键的匹配规则,将消息发送到匹配的队列。
绑定键可以使用通配符(* 表示匹配一个单词,# 表示匹配零个或多个单词)。

代码示例:

生产者:

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String routingKey, String message) {
    rabbitTemplate.convertAndSend("topicExchange", routingKey, message); // 发送消息到topic类型的交换机,并指定routingKey
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

消费者(可以有多个,每个消费者监听不同的路由键模式):

@RabbitListener(queues = "queueForTopicNews")
public void receiveNews(String message) {
    System.out.println("Received news message: " + message);
}

@RabbitListener(queues = "queueForTopicSports")
public void receiveSports(String message) {
    System.out.println("Received sports message: " + message);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

队列绑定到交换机时的配置(Spring配置类):

@Bean
Binding bindingNews(Queue queueForTopicNews, TopicExchange topicExchange) {
    return BindingBuilder.bind(queueForTopicNews).to(topicExchange).with("news.*"); // 匹配news.开头的routingKey
}

@Bean
Binding bindingSports(Queue queueForTopicSports, TopicExchange topicExchange) {
    return BindingBuilder.bind(queueForTopicSports).to(topicExchange).with("sports.#");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

8. 注解形式

参考问题6

9. 就目前而言,常用的rabbitmq配置方式有哪几种?

  • 一种是spring配置方式,代码直接创建交换机和队列,并绑定
  • 一种是springboot配置方式,配置类创建交换机和队列,并绑定
  • 一种是sopringboot注解方式,这种无需使用配置类
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/930206
推荐阅读
相关标签
  

闽ICP备14008679号