1. 程式人生 > >RabbitMQ三種Exchange模式(fanout,direct,topic)的效能比較

RabbitMQ三種Exchange模式(fanout,direct,topic)的效能比較

RabbitMQ中,所有生產者提交的訊息都由Exchange來接受,然後Exchange按照特定的策略轉發到Queue進行儲存

RabbitMQ提供了四種Exchange:fanout,direct,topic,header

header模式在實際使用中較少,本文只對前三種模式進行比較。

效能排序:fanout > direct >> topic。比例大約為11:10:6

一.Direct Exchange

0ec0f465-49c6-361c-ae2b-dd951a6ed1a9

 Direct Exchange - 處理路由鍵。需要將一個佇列繫結到交換機上,要求該訊息與一個特定的路由鍵完全匹配。這是一個完整的匹配。如果一個佇列繫結到該交換機上要求路由鍵 “dog”,則只有被標記為“dog”的訊息才被轉發,不會轉發dog.puppy,也不會轉發dog.guard,只會轉發dog。 

任何傳送到Direct Exchange的訊息都會被轉發到RouteKey中指定的Queue

1.一般情況可以使用rabbitMQ自帶的Exchange:”"(該Exchange的名字為空字串,下文稱其為default Exchange)。

2.這種模式下不需要將Exchange進行任何繫結(binding)操作

3.訊息傳遞時需要一個“RouteKey”,可以簡單的理解為要傳送到的佇列名字。

4.如果vhost中不存在RouteKey中指定的佇列名,則該訊息會被拋棄。

Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "direct"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey");  
  
byte[] messageBodyBytes = "hello world".getBytes();  
//需要繫結路由鍵  
channel.basicPublish("exchangeName", "routingKey", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);  

二.Fanout Exchange 

0bbdcd3d-9fc6-3107-b7e0-db67c174d46a

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

任何傳送到Fanout Exchange的訊息都會被轉發到與該Exchange繫結(Binding)的所有Queue上。

1.可以理解為路由表的模式

2.這種模式不需要RouteKey

3.這種模式需要提前將Exchange與Queue進行繫結,一個Exchange可以繫結多個Queue,一個Queue可以同多個Exchange進行繫結。

4.如果接受到訊息的Exchange沒有與任何Queue繫結,則訊息會被拋棄。

Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "fanout"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey");  
  
channel.queueDeclare("queueName1");  
channel.queueBind("queueName1", "exchangeName", "routingKey1");  
  
byte[] messageBodyBytes = "hello world".getBytes();  
//路由鍵需要設定為空  
channel.basicPublish("exchangeName", "", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);  

 

三.Topic Exchange

11171ab4-af07-3ff6-bdf6-d1febda679c3

 Topic Exchange – 將路由鍵和某模式進行匹配。此時佇列需要繫結要一個模式上。符號“#”匹配一個或多個詞,符號“*”匹配不多不少一個詞。因此“audit.#”能夠匹配到“audit.irs.corporate”,但是“audit.*” 只會匹配到“audit.irs”

任何傳送到Topic Exchange的訊息都會被轉發到所有關心RouteKey中指定話題的Queue上

1.這種模式較為複雜,簡單來說,就是每個佇列都有其關心的主題,所有的訊息都帶有一個“標題”(RouteKey),Exchange會將訊息轉發到所有關注主題能與

RouteKey模糊匹配的佇列。

2.這種模式需要RouteKey,也許要提前繫結Exchange與Queue。

3.在進行繫結時,要提供一個該佇列關心的主題,如“#.log.#”表示該佇列關心所有涉及log的訊息(一個RouteKey為”MQ.log.error”的訊息會被轉發到該佇列)。

4.“#”表示0個或若干個關鍵字,“*”表示一個關鍵字。如“log.*”能與“log.warn”匹配,無法與“log.warn.timeout”匹配;但是“log.#”能與上述兩者匹配。

5.同樣,如果Exchange沒有發現能夠與RouteKey匹配的Queue,則會拋棄此訊息。

Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "topic"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey.*");  
  
byte[] messageBodyBytes = "hello world".getBytes();  
channel.basicPublish("exchangeName", "routingKey.one", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);