RabbitMQ 的交換器(Exchange)

交換器(Exchange)是什麼?

當訊息寫入RabbitMQ時,並非直接將訊息寫入佇列中,而是透過交換器(Exchange)將訊息正確分派到佇列中,而依據就是訊息自帶的RouteKey是否與BindKey相符合;若完全沒有符合的佇列,則會自動遺棄該訊息。

交換器有哪幾種?

常用的交換器有四種 Direct, Fanout, Topic and Headers.

  • Direct: 預設的模式,即直接將訊息分配到 RouteKey 與 BindKey 完全相同的佇列上。
    Case1: BindKey: “log.info
    log.debug -> 不符合
    log.info -> 符合
    log.infomation -> 不符合
  • Fanout: 顧名思義就是將此訊息分配到每一個佇列上,等於是複製了n次。若設定fanout的話會自動忽略 BindKey與RouteKey。
  • Topic: Topic是較常用也是靈活度最高的模式,有點像是.net的routing概念,只要符合規格的RouteKey就會被傳遞到正確的queue。
    特殊符號分別是: * (一個任意字)與 # (零以上個任意字)。

    Case1:

    1
    2
    3
    4
    5
    BindKey: "*I.am.*"
    I.am.boy -> 符合
    I.am.girl -> 符合
    I.amNot.girl -> 不符合
    I.am.boy.too ->不符合

    Case2:

    1
    2
    3
    4
    BindKey "#.strong"
    He.is.strong -> 符合
    Not.strong -> 符合
    I.am.not.strong.neither -> 不符合
  • Headers: 從訊息中的header與BindKey做批配比較,並寫入queue中。這部分我也很少用,之後有特別研究再來補上怎麼使用。

    使用上的效能當然還是 fanout > direct > topic,但我認為除非在很極端的狀況下,否則比較這個的意義並不大,畢竟工具的使用還是以符合需求為主。
    另一點要注意的是RouteKey長度限制為255 bytes。

Fanout模式的演示

首先我們在宣告Exchange時將type指定為 “fanout”,當然在訂閱端也是需要的,程式碼一樣就不再貼上。

1
channel.ExchangeDeclare(exchange: "logs", type:"fanout");

其他部分沒有改變,將專案建置好後,開啟兩個訂閱者程式,然後執行Sender.exe以fanout模式送出一個訊息,就可以看到兩個視窗幾乎同時收到該訊息,且進行處理。
alt

程式範例檔

完整的範例檔放在這 範例,有興趣的可以自行下載。

  • 作者: MingYi Chou
  • 版權聲明: 轉載不用問,但請註明出處!本網誌均採用 BY-NC-SA 許可協議。