RabbitMQ系列-- 广播

在上一篇博客中,我们实现了工作队列,并且我们的工作队列中的一个任务只会发给一个工作者,除非某个工作者未完成任务意外被杀死,会转发给另外的工作者。 在这篇博客中,我们将实现将一个消息发给多个消费者,这种模式称之为广播。

本质上来说,就是发布的消息会转发给所有的接收者。

交换机(Exchanges)

前面的博客中我们都是通过生产者发送消息给队列,接收者从队列中接收消息。 接下来我们将引入Exchanges。

生产者只能将消息发送给Exchanges。 Exchanges一边从生产者接收消息,另一边将消息推送到队列中。我们可以通过定义转发器的类型进行定义它处理消息的方式。 可用的交换机的类型如下:

  1. Direct
  2. Topic
  3. headers
  4. fanout

目前我们只关注fanout。 fanout类型交换机特别简单,把所有它接收到的消息,广播到它所绑定的队列中。

在这里插入图片描述
在广播模式下,消息发送流程是这样的:

  • 可以有多个消费者
  • 每个消费者有自己的queue(队列)
  • 每个队列都要绑定到Exchange(交换机)
  • 生产者发送的消息,只能发送到交换机,交换机来决定要发送给哪个队列,生产者无法决定。
  • 交换机把消息发送给绑定过的所有队列
  • 队列的消费者都能拿到消息。实现一条消息被多个消费者消费。
代码实现

1.生产者:

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();

        //将通道声明指定交换机
        //参数1:交换机名称   参数2:交换机的类型  fanout 广播类型
        //没有交换机会创建一共名为logs的交换机
        channel.exchangeDeclare("logs","fanout");

        //发送消息
        channel.basicPublish("logs","",null,"fanout type message".getBytes());

        //关闭连接和通道
        RabbitMQUtils.closeChannelAndConnection(channel,connection);
    }
}

2.消费者1

public class Customer1 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("logs","fanout");

        //创建一个临时的、唯一的队列
        //返回的是 临时队列名
        String queueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        //参数1: 队列名称  参数2:交换机名称  参数3:路由名称
        channel.queueBind(queueName,"logs","");

        //消费消息
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}

3.消费者2

public class Customer2 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("logs","fanout");

        //创建一个临时的、唯一的队列
        //返回的是 临时队列名
        String queueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        //参数1: 队列名称  参数2:交换机名称  参数3:路由名称
        channel.queueBind(queueName,"logs","");

        //消费消息
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2:"+new String(body));
            }
        });
    }
}

4.消费者3

public class Customer3 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("logs","fanout");

        //创建一个临时的、唯一的队列
        //返回的是 临时队列名
        String queueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        //参数1: 队列名称  参数2:交换机名称  参数3:路由名称
        channel.queueBind(queueName,"logs","");

        //消费消息
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者3:"+new String(body));
            }
        });
    }
}

先运行3个消费者,在运行生产者,可以发送3个消费者都接收到了生产者发送的消息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值