消息发送流程说明
- 可以有多个消费者
- 每个消费者都有自己的队列(queue)
- 每个队列都要绑定到交换机(Exchange)(都是一些临时队列)
- 生产者发送的消息只能发送到交换机,交换机来决定要发给那个队列,生产者无法决定。
- 交换机将消息发送给绑定过的所有队列
- 队列的消费者都能拿到消息,实现一条消息被多个消费者消费
代码实现
生产者
public class ExSender {
private final static String EXCHANGE_NAME = "myex";
public static void main (String[] arsg) throws Exception{
//获取连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel =connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");//fanout发布订阅模式
//发送内容
channel.basicPublish(EXCHANGE_NAME,"",null,("发送消息").getBytes());
//关闭连接
channel.close();
connection.close();
}
}
消费者1
/**
* Created by wzy on 2020/12/7
* 消息接收者1
*/
public class ExRecver1 {
private final static String QUEUE = "myqueue1";
private final static String EXCHANGE_NAME = "myex";
public static void main (String[] arsg) throws Exception{
//获取连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel =connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE,false,false,false,null);
channel.basicQos(1);//执行的快就多干,执行的慢就少干
//将交换器与队列绑定
channel.queueBind(QUEUE,EXCHANGE_NAME,"");
//定义接收者
boolean autoAck = false;
channel.basicConsume(QUEUE, autoAck, "myConsumerTag",
new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("1body: " + new String(body));
//确认,false为确认收到消息,true为拒绝收到消息
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
}
消费者2
/**
* Created by wzy on 2020/12/7
* 消息接收者2
*/
public class ExRecver2 {
private final static String QUEUE = "myqueue2";
private final static String EXCHANGE_NAME = "myex";
public static void main (String[] arsg) throws Exception{
//获取连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel =connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE,false,false,false,null);
channel.basicQos(1);//执行的快就多干,执行的慢就少干
//将交换器与队列绑定
channel.queueBind(QUEUE,EXCHANGE_NAME,"");
//定义接收者
boolean autoAck = false;
channel.basicConsume(QUEUE, autoAck, "myConsumerTag",
new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("2body: " + new String(body));
//确认,false为确认收到消息,true为拒绝收到消息
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
}
结果
运行生产者发送一条消息,二个消费者同时接收到消息