Rabbit工作模式之发布订阅模式

    本文根据视频https://www.bilibili.com/video/BV1pa4y1x7Kc?p=7https://www.bilibili.com/video/BV1pa4y1x7Kc?p=8创作。未经视频作者授权,如果作者感到侵权,请联系本人删除此文

发布订阅模式结构图如下:

    

    发布订阅模式特点:

           生产者将消息发送给交换机;

           交换机绑定多个队列,每个消费者监听自己的队列;

           每个绑定交换机的队列都将收到消息。

    生产者代码实例:

public class PublishProducer {

    private static final String QUEUE_EMAIL = "queue_email";

    private static final String QUEUE_SMS = "queue_sms";

    private static final String EXCHANGE_FANOUT = "echange_fanout";

    public static void main(String[] args) {
        //通过连接工厂创建新的连接和MQ建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        //设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        Connection connection = null;
        Channel channel = null;
        try {
            //建立新的连接
            connection = connectionFactory.newConnection();
            //创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
            channel = connection.createChannel();
            //声明队列,如果队列在MQ中不存在则创建
            channel.queueDeclare(QUEUE_SMS, true, false, false,null);
            channel.queueDeclare(QUEUE_EMAIL, true, false, false,null);
            //声明交换机
            //参数: String exchange, String type
            /**
             * 参数明细
             * 1. exchange 交换机名称
             * 2. 交换机类型
             * fanout: 对应发布订阅模式
             * direct: 对应路由模式
             * topic: 对应通配符模式
             * headers: 对应header转发模式
             */
            channel.exchangeDeclare(EXCHANGE_FANOUT, BuiltinExchangeType.FANOUT);
            //绑定交换机和队列
            //参数: String queue, String exchange, String routingKey
            /**
             * 参数明细:
             * 1. queue 队列名称
             * 2. exchange 交换机名称
             * 3. routingKey 路由key,作用是交换机会根据路由key的值转发到指定的队列,在发布订阅模式为空串
             */
            channel.queueBind(QUEUE_EMAIL, EXCHANGE_FANOUT, "");
            channel.queueBind(QUEUE_SMS, EXCHANGE_FANOUT, "");
            //发送消息
            String message = "Hello World";
            channel.basicPublish(EXCHANGE_FANOUT, "", null, message.getBytes());
            System.out.println("send to mq " + message);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            //先关闭通道,在关闭连接
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

消费者代码实例一:

public class SubscriteConsumerEmail {

    private static final String QUEUE_EMAIL = "queue_email";

    private static final String EXCHANGE_FANOUT = "echange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException {
        //通过连接工厂创建新的连接和MQ建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        //设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        Connection connection = null;
        Channel channel = null;
        //建立新的连接
        connection = connectionFactory.newConnection();
        //创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
        channel = connection.createChannel();
        //声明队列,如果队列在MQ中不存在则创建
        channel.queueDeclare(QUEUE_EMAIL, true, false, false, null);
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_FANOUT, BuiltinExchangeType.FANOUT);
        //绑定交换机和队列
        channel.queueBind(QUEUE_EMAIL, EXCHANGE_FANOUT, "");

        //实现消费方法
        DefaultConsumer defaultConsumer = 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("receive message: " + message);
            }
        };

        //监听队列
        channel.basicConsume(QUEUE_EMAIL, true, defaultConsumer);
    }
}

消费者代码实例二:

    public static void main(String[] args) throws IOException, TimeoutException {
        //通过连接工厂创建新的连接和MQ建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        //设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        Connection connection = null;
        Channel channel = null;
        //建立新的连接
        connection = connectionFactory.newConnection();
        //创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
        channel = connection.createChannel();
        //声明队列,如果队列在MQ中不存在则创建
        channel.queueDeclare(QUEUE_SMS, true, false, false, null);
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_FANOUT, BuiltinExchangeType.FANOUT);
        //绑定交换机和队列
        channel.queueBind(QUEUE_SMS, EXCHANGE_FANOUT, "");

        //实现消费方法
        DefaultConsumer defaultConsumer = 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("receive message: " + message);
            }
        };

        //监听队列
        channel.basicConsume(QUEUE_SMS, true, defaultConsumer);
    }
}

猜你喜欢

转载自blog.csdn.net/wqc8994/article/details/106893121
今日推荐