RabbitMQJava 杂谈

rabbitmq5-发布订阅模式

2018-09-04  本文已影响0人  fkxuexi

前面的几篇博文中讲解的是两个简单的模式,并没有提到exchange交互及这个东西,那么是时候该引入完整的模式了,我们将引入exchange,同时介绍exchange的几种工作的模式

一、发布订阅模式概念及应用场景:

1、概念

发布订阅模式使用的是“fanout”扇出模式,即exchange将忽略routing key把其投递到所有绑定的队列中

2、应用场景:

二、关键组件“exchange”:

2.1、exchange的几种模式:
2.2 留一个问题思考一下:

三、把代码呈上来:

3.1、publisher:
public class Publisher {

    public static final String EXCHANGE_NAME = "publisher";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection conn = ConnUtils.getConn();
        Channel channel = conn.createChannel();
        BuiltinExchangeType type = BuiltinExchangeType.FANOUT;
        boolean durable = true;
        boolean autoDelete = false;
        /**
         * 是否为内部交换机,如果是则不能与外部client直接,通用用于例如死信队列
         */
        boolean internal = false;
        // 在这里最后一个参数还是不做讲解,在后面高级的部分在做讲解,死信队列、延迟队列、优先级队列
        channel.exchangeDeclare(EXCHANGE_NAME,type,durable,autoDelete,internal,null);
        // 这个里面我们不指定 routing key,因为没有意义,在fanout模式下会被忽视掉的
        channel.basicPublish(EXCHANGE_NAME,"",null,"我假装是你们想要发送的消息".getBytes());
    }
}
3.1、subscriber:

这个里面和官方给的代码不一样,如果不声明队列使用官方的形式的话,将会有一个临时的队列,

public class Subscriber01 {
    public static final String EXCHANGE_NAME = "publisher";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection conn = ConnUtils.getConn();
        final Channel channel = conn.createChannel();
        channel.queueDeclare("publisher",true,false,false,null);
        // 因为routing key会被忽略,所以还是无需指定
        // 这个地方queue:队列的名称是需要指定的
        channel.queueBind("publisher",EXCHANGE_NAME,"");
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(new String(body,"utf-8"));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        boolean autoAck = false;
        channel.basicConsume("publisher",autoAck,consumer);
    }
}

下面我们来回答上面的问题:
在上面的测试中,我们两个订阅者绑定的是同一个队列,结果只有其中的一个subscriber收到了消息,另外一个没有收到,这个是正常的,因为rabbitmq当消费者应答之后,mq会自动的把消息删除,现在我们看一下概念,发布订阅模式指的是:exchange忽略routing key把消息投递到所有的绑定它的队列,并不是说投递到所有的消费者,因此我们前面的假设都是有问题的,这也是我在学习的过程中算是胡思乱想的吧,希望大家能够明悟。

如果有疑问或者是需要交流可以在下面评论也可以扫码进群

上一篇 下一篇

猜你喜欢

热点阅读