rabbitmq_03_发布订阅/广播()

一、模型图

  • P:生产者
  • X:交换机
  • 红色:临时队列
  • C1:消费者1
  • C2: 消费者2

在广播模式下,消息发送流程是这样的:

  • 可以有多个消费者
  • 每个消费者有自己的queue(队列)
  • 每个队列都要绑定到exchange(交换机)
  • 交换机把消息发送给绑定过的所有队列
  • 队列的i西奥菲这都能拿到消息,实现一条消息被多个消费者消费

二、代码演示

1、工具类

package com.java.study.rabbitmq.utils;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitMQUtils {

    private static ConnectionFactory connectionFactory;
    static{
        //1.创建连接mq的连接工厂对象
        connectionFactory = new ConnectionFactory();
        //2.设置连接rabbitmq主机
        connectionFactory.setHost("192.168.8.222");
        //3.设置端口号
        connectionFactory.setPort(5672);
        //4.设置连接那个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //5.设置访问虚拟主机的用户名和密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");
    }

    public static Connection getConnections(){
        try{
            //6.获取连接
            return connectionFactory.newConnection();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static void closeConnectionAndChannel(Channel channel,Connection connection){
        try {
            channel.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2、生产者

package com.java.study.rabbitmq.fanout;

import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.junit.Test;

public class Producer {
    private final static String EXCHANGE_NAME = "logs";
    private final static String EXCHANGE_TYPE = "fanout";

    @Test
    public void sendMessages() throws Exception {
        //6.获取连接
        Connection connection = RabbitMQUtils.getConnections();
        //7.获取通道
        Channel channel = connection.createChannel();

        //8.将通道声明指定的交换机
        //参数1:交换机的名字
        //参数2:交换机的类型
        channel.exchangeDeclare(EXCHANGE_NAME,EXCHANGE_TYPE);

        String message = "fanout type message";
        //9.发布消息
        //参数1:exchange 交换机名称
        //参数2:routingKey 队列名称(由这里具体指定发送到具体哪个队列中)
        //参数3:props 传递消息额外设置(由这里设置消息是否持久化,MessageProperties.PERSISTENT_TEXT_PLAIN:重启不会消失)
        //参数4:body 消息的具体内容
        channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes());

        //10.关闭连接
        RabbitMQUtils.closeConnectionAndChannel(channel,connection);
    }
}

3、消费者1

package com.java.study.rabbitmq.fanout;

import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer1 {
    private final static String EXCHANGE_NAME = "logs";
    private final static String EXCHANGE_TYPE = "fanout";

    public static void main(String[] args) throws Exception{
        //6.获取连接
        Connection connection = RabbitMQUtils.getConnections();

        //7.获取通道
        Channel channel = connection.createChannel();

        //8.通道绑定交换机
        channel.exchangeDeclare(EXCHANGE_NAME,EXCHANGE_TYPE);

        //9.临时队列
        String queueName = channel.queueDeclare().getQueue();

        //10.绑定交换机和队列
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        //11.消费消息
        //参数1:队列名称
        //参数2:消息的自动确认机制 true:消费者自动向rabbitmq确认消息消费(拿到即确认,遇到异常消息丢失) false:手动确认
        //参数3:消费消息时的回调接口
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            //参数1:consumerTag 消费者标签,用来标识消费者的,在
            //参数2:envelope 信封
            //参数3:properties 消息属性
            //参数4:body 消息队列中取出的消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}

4、消费者2

package com.java.study.rabbitmq.fanout;

import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer2 {
    private final static String EXCHANGE_NAME = "logs";
    private final static String EXCHANGE_TYPE = "fanout";

    public static void main(String[] args) throws Exception{
        //6.获取连接
        Connection connection = RabbitMQUtils.getConnections();
        //7.获取通道
        Channel channel = connection.createChannel();

        //8.通道绑定交换机
        channel.exchangeDeclare(EXCHANGE_NAME,EXCHANGE_TYPE);

        //9.临时队列
        String queueName = channel.queueDeclare().getQueue();

        //10.绑定交换机和队列
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        //11.消费消息
        //参数1:队列名称
        //参数2:消息的自动确认机制 true:消费者自动向rabbitmq确认消息消费(拿到即确认,遇到异常消息丢失) false:手动确认
        //参数3:消费消息时的回调接口
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            //参数1:consumerTag 消费者标签,用来标识消费者的,在
            //参数2:envelope 信封
            //参数3:properties 消息属性
            //参数4:body 消息队列中取出的消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2:"+new String(body));
            }
        });
    }
}

5、消费者3

package com.java.study.rabbitmq.fanout;

import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer3 {
    private final static String EXCHANGE_NAME = "logs";
    private final static String EXCHANGE_TYPE = "fanout";

    public static void main(String[] args) throws Exception{
        //6.获取连接
        Connection connection = RabbitMQUtils.getConnections();
        //7.获取通道
        Channel channel = connection.createChannel();

        //8.通道绑定交换机
        channel.exchangeDeclare(EXCHANGE_NAME,EXCHANGE_TYPE);

        //9.临时队列
        String queueName = channel.queueDeclare().getQueue();

        //10.绑定交换机和队列
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        //11.消费消息
        //参数1:队列名称
        //参数2:消息的自动确认机制 true:消费者自动向rabbitmq确认消息消费(拿到即确认,遇到异常消息丢失) false:手动确认
        //参数3:消费消息时的回调接口
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            //参数1:consumerTag 消费者标签,用来标识消费者的,在
            //参数2:envelope 信封
            //参数3:properties 消息属性
            //参数4:body 消息队列中取出的消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者3:"+new String(body));
            }
        });
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值