消息的路由模式

消息的路由模式

https://www.jianshu.com/p/e87a467e4d56
RabbitMQ提供了四種交換器,分別是
Direct交換器、Fanout交換器、Topic交換器、Headers交換器

注:
交換機,接收發送到RabbitMQ中的消息並決定把他們投遞到那個隊列的組件。
這裏的交換器決定了消息會投遞到哪一個隊列當中。

Direct(默認的隊列方式,完全匹配):把消息路由到那些binding key與routing key完全匹配的Queue中

  • 通過路由鍵來進行交換器與隊列進行綁定
    在這裏插入圖片描述
    Fanout(一種廣播模式,不涉及路由):路由規則是把所有發送到該Exchange的消息路由到所有與它綁定的Queue中

  • 不處理路由鍵,給所有綁定的隊列都發送
    在這裏插入圖片描述
    Topic(有條件的選擇路由,也是一種廣播模式):模糊匹配,通過通配符滿足一部分規則就可以傳送,其中注意的是有兩個字符 ‘星號’ 和#號,
    其中 *號 用於匹配一個單詞,#號用於匹配多個單詞(可以是0個)

  • 根據route key 匹配隊列,可以是一對多的關係(這裏指定是匹配關係)

  • topic交換器會將消息路由至匹配路由至路由鍵的任一隊列中。(只會有一個隊列會接收到這個消息)

Headers(可以實現類似於topic的效果):它通過採用消息屬性中的headers表支持任意的路由策略。

  • Headers通過source、object和action取代了路由鍵的作用。
  • 這種使用方式通常使用在headers屬性中使用了非常巨大的表值,否則消息的發佈速率不會有很大提升。
  • 這種方式也可以結合一致性hash算法對header-type進行hash運算後實現加權負載均衡式的消息投遞。

在實際的項目中,通常在生產者定義的時候將交換器與隊列進行綁定
這裏以Topic方式爲例

/**
* @author Gjing
**/@Configurationpublic class RabbitMqConfiguration {


    /**
     * 聲明一個名爲topic.message1的隊列
     */
    @Bean
    public Queue topicQueue() {
        return new Queue("topic.message1");
    }


    /**
     * 聲明一個名爲topic.message2的隊列
     */
    @Bean
    public Queue topicQueue2() {
        return new Queue("topic.message2");
    }


    /**
     * 聲明一個名爲exchange的交換機
     *
     */
    @Bean
    public TopicExchange exchange() {
        return new TopicExchange("exchange");
    }


    /**
     * 將topic.message1的隊列綁定到exchange交換機
     */
    @Bean
    public Binding bindMessage1() {
        return BindingBuilder.bind(topicQueue()).to(exchange()).with("topic.message1");
    }


    /**
     * 將topic.message2的隊列綁定到exchange交換機
     */
    @Bean
    public Binding bindMessage2() {
        return BindingBuilder.bind(topicQueue2()).to(exchange()).with("topic.message2");
    }}

發佈端

  • this.rabbitTemplate.convertAndSend(交換器,路由鍵,消息)
  • topic模式中匹配的在聲明隊列時指定的路由鍵new Queue(“topic.message2”)
/**
* @author Gjing
**/@Componentpublic class TopicProducer {
    @Resource
    private AmqpTemplate rabbitTemplate;
    public void send() {
        String message1 = "I am topic.message1";
        String message2 = "I am topic.message2";
        this.rabbitTemplate.convertAndSend("exchange", "topic.*", message1);
        this.rabbitTemplate.convertAndSend("exchange", "topic.*", message2);
    }}

消費端

  • 消費者消費的是監聽一個或者多個隊列中的消息
  • 這裏的消費端會消費隊列“topic.message2”中的消息
/**
* @author Gjing
**/@Component@Slf4jpublic class TopicConusmer2 {
    @RabbitListener(queues = "topic.message2")
    public void receive(String message) {
        log.info("消費者2收到消息:{}", message);
    }}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章