在之前的例子中,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.....'