发布/订阅
- 生产者是发送消息的用户的应用程序。
- 队列是存储消息的缓冲器。
- 消费者是接收消息的用户的应用程序。
RabbitMQ中消息传递模型的核心思想是生产者永远不会将任何消息直接发送到队列。实际上,生产者通常甚至不知道消息是否会被传递到任何队列。、
生产者只能向Exchange发送消息。交换是一件非常简单的事情。一方面,它接收来自生产者的消息,另一方面将它们推送到队列。exchange所必须确切知道如何处理收到的消息。它应该附加到特定队列吗?它应该附加到许多队列吗?或者它应该被丢弃。其规则由交换类型定义 。
Exchange有四个类型,direct, topic, headers and fanout
channel.exchangeDeclare("logs", "fanout");//第一个参数是Exchange的名字,第二参数是类型
fanout是把消息广播到所有的队列中
无名exchange是默认创建的,就是不显示创建exchange的话就会默认创建一个无名的exchange,无名的exchange消息被路由到具有routingKey指定名称的队列(如果存在)。
临时队列
首先,每当我们连接到Rabbit时,需要一个新的空队列时。为此,我们可以使用随机名称创建队列,或者更好 - 让服务器为我们选择随机队列名称。
其次,一旦我们断开消费者,就应该自动删除队列。
String queueName = channel.queueDeclare().getQueue();//随机队列
在Java客户端中,当我们没有向queueDeclare()提供参数时,我们 使用生成的名称创建一个非持久的,独占的自动删除队列
绑定(binding)
exchange和Queue直接的关系叫做绑定(binding)
channel.queueBind(queueName,“logs”,“”);
显示实例代码
生产者
import java.io.IOException;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
public class EmitLog {
private static final String EXCHANGE_NAME = "logs";
public static void main(String[] argv)
throws java.io.IOException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String message = getMessage(argv);
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
//...
private static String getMessage(String[] strings){
if (strings.length < 1)
return "Hello World!";
return joinStrings(strings, " ");
}
private static String joinStrings(String[] strings, String delimiter) {
int length = strings.length;
if (length == 0) return "";
StringBuilder words = new StringBuilder(strings[0]);
for (int i = 1; i < length; i++) {
words.append(delimiter).append(strings[i]);
}
return words.toString();
}
}
消费者
import com.rabbitmq.client.*;
import java.io.IOException;
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();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String queueName = channel.queueDeclare().getQueue();
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);
}
}