Spring Boot RabbitMQ - 交換器

fanout exchange

發送到該交換器的所有消息,會被路由到其綁定的所有隊列。不處理路由鍵。你只需要簡單的將隊列綁定到交換機上。一個發送到交換機的消息都會被轉發到與該交換機綁定的所有隊列上。很像子網廣播,每臺子網內的主機都獲得了一份複製的消息。Fanout交換機轉發消息是最快的。

如圖所示,所有發送到 fanout exchange 的消息都會路由到 QUEUE-1 和 QUEUE-2

direct exchange

發送到該交換器的消息,會通過路由鍵完全匹配,匹配成功就會路由到指定隊列

處理路由鍵。需要將一個隊列綁定到交換機上,要求該消息與一個特定的路由鍵完全匹配。這是一個完整的匹配。如果一個隊列綁定到該交換機上要求路由鍵 “abc”,則只有被標記爲“abc”的消息才被轉發,不會轉發abc.def,也不會轉發dog.ghi,只會轉發abc。

如圖所示,發送到 direct exchange 的消息,會通過消息的 routing key 路由:

  • 如果 routing key 值爲 queue.direct.key1,會路由到 QUEUE-1
  • 如果 routing key 值爲 queue.direct.key2,會路由到 QUEUE-2
  • 如果 routing key 值爲其他,不會路由到任何隊列

topic exchange

發送到該交換器的消息,會通過路由鍵模糊匹配,匹配成功就會路由到指定隊列

將路由鍵和某模式進行匹配。此時隊列需要綁定要一個模式上。符號“#”匹配一個或多個詞,符號“”匹配不多不少一個詞。因此“abc.#”能夠匹配到“abc.def.ghi”,但是“abc.” 只會匹配到“abc.def”。

路由鍵通過 . 來劃分爲多個單詞, * 匹配一個單詞,# 匹配零個或多個單詞

如圖所示,發送到 topic exchange 的消息,會通過消息的 routing key 模糊匹配再路由:

  • 如果 routing key 值爲 queue.topic.key1,會路由到 QUEUE-1 和 QUEUE-2
  • 如果 routing key 值爲 test.topic.key2,會路由到 QUEUE-1
  • 如果 routing key 值爲 queue,會路由到 QUEUE-2
  • 如果 routing key 值爲 queue.hello,會路由到 QUEUE-2
  • 如果 routing key 值爲 test.test.test,不會路由到任何隊列

header exchange

發送到該交換器的消息,會通過消息的 header 信息匹配,匹配成功就會路由到指定隊列。

不處理路由鍵。而是根據發送的消息內容中的headers屬性進行匹配。在綁定Queue與Exchange時指定一組鍵值對;當消息發送到RabbitMQ時會取到該消息的headers與Exchange綁定時指定的鍵值對進行匹配;如果完全匹配則消息會路由到該隊列,否則不會路由到該隊列。headers屬性是一個鍵值對,可以是Hashtable,鍵值對的值可以是任何類型。而fanout,direct,topic 的路由鍵都需要要字符串形式的。

匹配規則x-match有下列兩種類型:

x-match = all :表示所有的鍵值對都匹配才能接受到消息

x-match = any :表示只要有鍵值對匹配就能接受到消息

消息的 header 信息是 key-value 的形式,每條消息可以包含多條 header 信息,路由規則是通過 header 信息的 key 來匹配的,Spring Boot 封裝的匹配規則有三種:

  • where(key).exists() :匹配單個 key
  • whereAll(keys).exist() :同時匹配多個 key
  • whereAny(keys).exist() :匹配多個 key 中的一個或多個

如圖所示,發送到 headers exchange 的消息,會通過消息的 header 匹配:

 

@Bean    Binding bindingHeadersQueue1(Queue headersQueue1, HeadersExchange headersExchange) {        return BindingBuilder.bind(headersQueue1).to(headersExchange).where("one").exists();    }
    @Bean    Binding bindingHeadersQueue2(Queue headersQueue1, HeadersExchange headersExchange) {        return BindingBuilder.bind(headersQueue1).to(headersExchange).whereAll("all1", "all2").exist();    }
    @Bean    Binding bindingHeadersQueue3(Queue headersQueue3, HeadersExchange headersExchange) {        return BindingBuilder.bind(headersQueue3).to(headersExchange).whereAny("any1", "any2").exist();    }

如果 header 信息存在 one=XXXX,會路由到 QUEUE-1

如果 header 信息存在 all1=XXXX 和 all2=XXXX,會路由到 QUEUE-2

如果 header 信息存在 any1=XXXX 或 any2=XXXX,會路由到 QUEUE-3

提示:header 不能以 x- 開頭

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章