RabbitMQ有四種Exchange類型,分別是Direct 、Fanout 、Topic、Headers Exchange特點: Fanout 不處理路由鍵。你只需要簡單的將隊資料行繫結到交換器上。一個發送到該類型交換器的訊息都會被廣播到與該交換器綁定的所有隊列上。如下圖:
Topic 將路由鍵和某模式進行匹配。此時隊列需要綁定要一個模式上。符號“#”匹配一個或多個詞,符號“*”只能匹配一個詞。因此“logs.#”能夠匹配到“logs.error”、“logs.info.toc”,但是“logs.*” 只能匹配到“logs.error”,不能匹配到“logs.info.toc” 。如下圖:
Direct 處理路由鍵,需要將一個隊資料行繫結到交換器上,要求該訊息與一個特定的路由鍵完全符合。這是一個完整的匹配。如果一個隊資料行繫結到該交換器上要求路由鍵為 “logs”,則只有路由鍵為“logs”的訊息才被轉寄,不會轉寄路由鍵為"logs.error",只會轉寄路由鍵為"logs"。 如下圖:
Headers 不處理路由鍵,而是根據發送的訊息內容中的headers屬性進行匹配。在綁定Queue與Exchange時指定一組索引值對;當訊息發送到RabbitMQ時會取到該訊息的headers與Exchange綁定時指定的索引值對進行匹配;如果完全符合則訊息會路由到該隊列,否則不會路由到該隊列。headers屬性是一個索引值對,可以是Hashtable,索引值對的值可以是任何類型。而fanout,direct,topic 的路由鍵都需要要字串形式的。不過headers比較少用到,下面是headers的官方說明文檔: A headers exchange is designed to for routing on multiple attributes that are more easily expressed as message headers than a routing key. Headers exchanges ignore the routing key attribute. Instead, the attributes used for routing are taken from the headers attribute. A message is considered matching if the value of the header equals the value specified upon binding. It is possible to bind a queue to a headers exchange using more than one header for matching. In this case, the broker needs one more piece of information from the application developer, namely, should it consider messages with any of the headers matching, or all of them? This is what the "x-match" binding argument is for. When the "x-match" argument is set to "any", just one matching header value is sufficient. Alternatively, setting "x-match" to "all" mandates that all the values must match. Headers exchanges can be looked upon as "direct exchanges on steroids". Because they route based on header values, they can be used as direct exchanges where the routing key does not have to be a string; it could be an integer or a hash (dictionary) for example.
有了上面的介紹,下面就直接上代碼吧。。
Consumer:
package fanout;import java.io.IOException;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Consumer;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.Envelope;public class FanoutConsumer {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();//rabbitmq監聽IPfactory.setHost("192.168.249.128");//rabbitmq監聽預設連接埠factory.setPort(5672);//設定訪問的使用者factory.setUsername("test");factory.setPassword("test");Connection connection = factory.newConnection();Channel channel = connection.createChannel();//聲明路由名字和類型channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//擷取隨機隊列名稱String queueName = channel.queueDeclare().getQueue();//建立隊列channel.queueDeclare(queueName, false, false, true, null);//把隊資料行繫結到路由上channel.queueBind(queueName, EXCHANGE_NAME, "");System.out.println(" Waiting for msg....");Consumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body) throws IOException {String message = new String(body, "UTF-8");System.out.println("Received msg is '" + message + "'");}};channel.basicConsume(queueName, true, consumer);}}
Producer:
package fanout;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;public class FanoutProducer {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception{ConnectionFactory factory = new ConnectionFactory();//rabbitmq監聽IPfactory.setHost("192.168.249.128");//rabbitmq監聽預設連接埠factory.setPort(5672);//設定訪問的使用者factory.setUsername("test");factory.setPassword("test");Connection connection = factory.newConnection();Channel channel = connection.createChannel();//聲明路由名字和類型channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String message = makeMessage(argv);channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());System.out.println("Sent msg is '" + message + "'");channel.close();connection.close();}private static String makeMessage(String[] strings){if (strings.length < 1){return "這是預設訊息。。";}else{StringBuffer buffer= new StringBuffer();for (int i = 0; i < strings.length; i++) {buffer.append(strings[i]);}return buffer.toString();}}}
運行 Consumer:
運行 Producer:
好了 , 就到這裡~~ 祝生活愉快。。。