RabbitMq之Publish/Subscribe

在之前的例子中,rabbit傳遞消息的形式如下:

1.send發送消息到指定的一個隊列中

2.隊列充當一個消息存儲容器.

3.consumer從隊列中消費消息.

當存在多個consumer消費者的時候,rabbitmq會比較平均的分配消息給每個consumer,也就是說,每個consumer獲取的消息都是隊列消息的一個子集.

而在發佈/訂閱這種模式中,消息傳遞模型的核心思想是,生產者不發送任何信息直接到隊列。事實上,生產者也不知道消息是否會被傳送到任何隊列。 rabbitmq引入了一箇中間者exchanges. 

Exchanges

1.send發送消息到指定的一個exchanges中

2.可以將任意的隊列綁定到exchanges中,並且消息會隨着exchanges的廣播發送到隊列中

3.隊列充當一個消息存儲容器.

4.consumer從隊列中消費消息.

生產者只能發送消息到Exchange。exchanges是件很簡單的事。一方面它接收來自生產者和另一方的消息,並將它們推送到隊列中。Exchange必須知道它接收哪些消息。是否應該附加到特定隊列?它應該被附加到多個隊列嗎?或者它應該被丟棄。該規則由Exchange類型定義。 

exchanges有幾種類型:direct, topic, headers and fanout

更多請查看:http://blog.csdn.net/yzr_java/article/details/70916084

Listing exchanges

可以在命令行中監聽exchanges:    rabbitmqctl list_exchanges

Temporary queues

臨時隊列:由rabbitmq服務器自動創建的隊列,當連接關閉時,臨時隊列將會被自動刪除.

exchanges可以配合使用臨時隊列,將消息廣播到臨時隊列中.

//服務器創建隊列
String queueName = channel.queueDeclare().getQueue();

Bindings

將隊列綁定到exchanges中,當exchanges進行廣播的時候,被綁定的隊列將會接收到消息.

//將隊列綁定到exchange
channel.queueBind(queueName, EXCHANGE_NAME, "");

Listing bindings

可以使用命令行監聽: rabbitmqctl list_bindings

package yzr.main;

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 ReceiveLogs {

	private static final String EXCHANGE_NAME = "logs";

	  public static void main(String[] argv) throws Exception {
	    ConnectionFactory factory = new ConnectionFactory();
	    factory.setHost("localhost");
	    Connection connection = factory.newConnection();
	    Channel channel = connection.createChannel();
	    //創建exchange
            //fanout將消息廣播到隊列中
	    channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	    //服務器創建隊列
	    String queueName = channel.queueDeclare().getQueue();
	    //將隊列綁定到exchange
	    channel.queueBind(queueName, EXCHANGE_NAME, "");

	    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

	    Consumer consumer = new DefaultConsumer(channel) {
	      @Override
	      public void handleDelivery(String consumerTag, Envelope envelope,
	                                 AMQP.BasicProperties properties, byte[] body) throws IOException {
	        String message = new String(body, "UTF-8");
	        System.out.println(" [x] Received '" + message + "'");
	      }
	    };
	    channel.basicConsume(queueName, true, consumer);
	  }

}


測試:

啓動上面的ReceiveLogs類,然後http://localhost:15672登陸之後看一下exchanges視圖:


然後再看一下隊列視圖:


發送消息:

 [x] Sent '111 message.'
 [x] Sent '211 message..'
 [x] Sent '311 message...'
 [x] Sent '411 message....'
 [x] Sent '511 message.....'
 [x] Sent '611 message.....'
 [x] Sent '711 message.....'
 [x] Sent '811 message.....'
 [x] Sent '911 message.....'


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