消息队列RabbitMQ.02.交换机的讲解与使用

发布时间:2024年01月23日

目录

RabbitMQ中交换机的基本概念与作用解析

交换机的作用:

交换机的类型:

直连交换机(Direct Exchange):?将消息路由到与消息中的路由键(Routing Key)完全匹配的队列。

主题交换机(Topic Exchange):?使用通配符匹配路由键,允许更灵活的消息路由。

扇形交换机(Fanout Exchange):?将消息广播到与交换机绑定的所有队列,无视消息的路由键。

头部交换机(Headers Exchange):?使用消息头信息进行匹配,而不是路由键。

死信交换机(Dead Letter Exchange)是在消息队列系统中一种用于处理死信(Dead Letter Messages)的机制。死信通常是指由于某些原因而无法被成功处理的消息,这些原因可能包括消息过期、消息被拒绝、队列满等。

?个人总结:


RabbitMQ中交换机的基本概念与作用解析


交换机的作用:

  • 消息分发:?交换机接收发布者发送的消息,并负责将消息路由到一个或多个队列。
  • 路由规则定义:?通过交换机可以定义消息的路由规则,以确保消息被正确地发送到目标队列。

交换机的类型:

  • 直连交换机(Direct Exchange):?将消息路由到与消息中的路由键(Routing Key)完全匹配的队列。

直连交换机只能通过queue发送一个请求,如果需要发送多个请求那么就要进行多个配置

//--------直连交换机
    @Bean
    public Queue queue1() {
        return new Queue("queue1");
    }

    @Bean
    public Queue queue2() {
        return new Queue("queue2");
    }

    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("exchange1");
    }

    @Bean
    public Binding binding01(){
        return BindingBuilder
                .bind(queue1())
                .to(directExchange())
                .with("aa");
    }
    @Bean
    public Binding binding02(){
        return BindingBuilder
                .bind(queue2())
                .to(directExchange())
                .with("bb");
    }

?消费者接受信息

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "queue1")
public class ReceiverQ1 {

    @RabbitHandler
    public void process(String msg) {
        log.warn("q1接收到:" + msg);
    }
}

测试

@RestController
public class TestController {

    @Autowired
    private AmqpTemplate template;
    @Autowired
    private ObjectMapper objectMapper;

   
    @RequestMapping("/send3")
    public String send3(){
        template.convertAndSend("directExchange","aa","hello");
        return "🤣";
    }


}

?


  • 主题交换机(Topic Exchange):?使用通配符匹配路由键,允许更灵活的消息路由。
  1. 通配符的含义:

    • 星号(*):?匹配一个单词,可以出现在路由键的任意位置。例如,"animal.*"匹配"animal.rabbit"和"animal.cat"等。
    • 井号(#):?匹配零个或多个单词,只能出现在路由键的末尾。例如,"animal.#"匹配"animal.rabbit"、"animal.cat"和"animal.mammal.large"等。

主题交换机可以通过配置多个路由键来实现不同的键进入不同的消费者,如:交换机a,交换机b,

现在有一个包含a和b的键那么两个都能进入不同的消费者功能更加强大,并且可以配置通配符,根据通配符 * #? 来实现进入不同的消费者

//--------------主题交换机
    // *.*.aa -> Q1
    // *.*.bb -> Q2
    // mq.# -> Q1,Q2
    // 一个队列可以用多个绑定键

    @Bean
    public TopicExchange topicExchange(){
        return  new TopicExchange("topicExchange");
    }

    @Bean
    public Binding binding03(){
        return BindingBuilder
                .bind(queue1())
                .to(topicExchange())
                .with("*.*.aa");
    }

    @Bean
    public Binding binding04(){
        return BindingBuilder
                .bind(queue2())
                .to(topicExchange())
                .with("*.*.bb");
    }

    @Bean
    public Binding binding05(){
        return BindingBuilder
                .bind(queue1())
                .to(topicExchange())
                .with("mq.#");
    }

    @Bean
    public Binding binding06(){
        return BindingBuilder
                .bind(queue2())
                .to(topicExchange())
                .with("mq.#");
    }

测试


@RestController
public class TestController {

    @Autowired
    private AmqpTemplate template;
    @Autowired
    private ObjectMapper objectMapper;

   
     @RequestMapping("/send4")
    public String send4(String rex){
        template.convertAndSend("topicExchange",rex,"hello");
        return "🤣";
    }



}

?


  • 扇形交换机(Fanout Exchange):?将消息广播到与交换机绑定的所有队列,无视消息的路由键。

扇形交换机可以统一发送请求,列入可以运用到,商城活动时统一给用户发送商城活动信息

//--------------扇形交换机
    // 广播,群发
    //它上面的队列不需要binding key

    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanoutExchange");
    }
    @Bean
    public Binding binding07(){
        return BindingBuilder
                .bind(queue1())
                .to(fanoutExchange());
    }
    @Bean
    public Binding binding08(){
        return BindingBuilder
                .bind(queue2())
                .to(fanoutExchange());
    }

测试代码

 @RequestMapping("/send5")
    public String send5(){
        template.convertAndSend("fanoutExchange","","hello");
        return "🤣";
    }

?上述效果图:


?

  • 头部交换机(Headers Exchange):?使用消息头信息进行匹配,而不是路由键。

头部交换机(Headers Exchange)是RabbitMQ中的一种交换机类型,与其他类型的交换机(直连交换机、主题交换机、扇出交换机)不同,头部交换机使用消息的头信息(Headers)而不是路由键来进行消息的路由。头部交换机提供更灵活的路由方式,允许根据消息头的键值对进行匹配。

?以下是头部交换机的一些关键特性和使用方式:

  1. 消息头信息:

    • 键值对:?消息头是由一系列键值对组成的,用于描述消息的属性。
    • 自定义属性:?消息头可以包含自定义的属性,根据应用程序的需要定义不同的属性信息。
  2. 匹配规则:

    • 匹配方式:?消息通过匹配消息头的键值对来确定路由目标。
    • 多条件匹配:?可以定义多个键值对,消息需要满足所有条件才能被正确路由。
  3. 绑定关系:

    • 绑定头信息:?在绑定队列到头部交换机时,可以指定一个或多个键值对作为匹配条件。
    • 匹配算法:?消息头需要匹配绑定队列时指定的键值对条件,才能被路由到相应的队列。
  4. 使用场景:

    • 复杂路由逻辑:?当消息的路由逻辑需要根据多个条件进行判断时,头部交换机提供了更灵活的解决方案。
    • 自定义属性:?当消息携带有多个自定义属性,需要根据这些属性进行复杂匹配时,头部交换机是一个合适的选择。
  5. 示例:

    • 如果有一个消息头包含"content-type"为"application/json",并且"priority"为"high",一个队列可以通过绑定这两个条件到头部交换机来接收符合这两个条件的消息。
    • 另一个队列可以通过绑定"content-type"为"application/xml"的条件来接收不同类型的消息。

头部交换机适用于需要根据消息的多个属性进行复杂匹配的场景,提供了更高度定制化的消息路由能力。


  • 死信交换机(Dead Letter Exchange)是在消息队列系统中一种用于处理死信(Dead Letter Messages)的机制。死信通常是指由于某些原因而无法被成功处理的消息,这些原因可能包括消息过期、消息被拒绝、队列满等。

以下是关于死信交换机的基本概念和作用:

  1. 死信的产生原因:

    • 消息过期:?消息在队列中等待的时间超过了指定的过期时间。
    • 消息被拒绝:?消费者拒绝消费消息,并且消息被标记为不可重新投递。
    • 队列满:?队列达到最大容量,无法再接收新的消息。
  2. 死信交换机的作用:

    • 死信路由:?当消息被标记为死信时,它会被发送到死信交换机。
    • 重新处理或记录:?可以通过死信交换机重新将消息发送到其他队列,进行额外处理,或者记录日志以分析死信的原因。
  3. 死信交换机的配置:

    • 绑定关系:?死信交换机与原始交换机或队列建立绑定关系。
    • 死信队列:?定义一个死信队列,接收由死信交换机路由的死信。
    • 死信交换机类型:?死信交换机可以是不同类型的交换机,根据具体需求选择合适的类型。
  4. 应用场景:

    • 错误处理:?处理由于消息格式错误等原因导致的死信。
    • 重试机制:?将死信重新发送到其他队列进行重试。
    • 日志记录:?记录死信信息以便进行故障排除和分析。

使用死信交换机可以提高消息系统的健壮性和可靠性,确保无法正常处理的消息得到妥善处理,避免消息的丢失或无法追踪。配置死信交换机需要根据具体消息队列系统的实现进行设置,例如在RabbitMQ中,可以通过设置交换机和队列的参数来实现死信机制。

?


?个人总结:

1.直连交换机只能通过queue发送一个请求,如果需要发送多个请求那么就要进行多个配置;

2.主题交换机可以通过配置多个路由键来实现不同的键进入不同的消费者,如:交换机a,交换机b,现在有一个包含a和b的键那么两个都能进入不同的消费者功能更加强大,并且可以配置通配符,根据通配符 * #? 来实现进入不同的消费者;

3. * 星号代表匹配一个单词,# 井号代表匹配一个或多个单词;

4.扇形交换机可以统一发送请求,列入可以运用到,商城活动时统一给用户发送商城活动信息;

文章来源:https://blog.csdn.net/d2916172682/article/details/135775817
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。