RabbitMQ-发布订阅

发布与订阅

在上一个教程中,我们创建一个工作队列,我们将每个人物,最终恰好分配到一个工人。然而,在这个部分,我们希望每个消息能分配给多个消费者。这种叫发布订阅模式。举例,注册时需要同时发送短信和发送email,我们会将用户注册的信息发给两个消费者,一个专门发送短信消费者,一个专门发送email消费者。

RabbitMQ消息传递模型的核心思想是,生产者不直接想消息队列发送信息。实际上,生产者并不知道消息是否会被传递到任何队列上。

交换机

这里就讲到一个新型概念,交换机(exchange),一方面接收生产者的信息,一方面推送给队列。交换器必须确切地知道如何处理它接收到的消息。它应该被附加到一个特定的队列吗?它应该被添加到许多队列中吗?或者它应该被丢弃。这些规则由exchange类型定义。有几种可用的交换类型:direct、topic、headers和fanout。下面讲:fanout,是一个比较简单的类型。只是将消息广播到它知道的所有队列中去。下图中X就是交换机。

exchange模型图

生产者

public class Send {
    private final static String EXCHANGE_NAME = "test_exchange_fanout";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection() ;
        Channel channel = connection.createChannel();
        // 声明队列
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);//分发类型fanout
        String msg = "hello world ps";
        // 发送信息
        channel.basicPublish(EXCHANGE_NAME,"",null,msg.getBytes());
        System.out.println("send success");
        // 关闭流
        channel.close();
        connection.close();
    }
}
消费者
public class Rece1 {
    private final static String QUEUE_NAME = "test_queu_email";
    private final static String EXCHANGE_NAME = "test_exchange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        // 绑定队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        // 绑定队列到交换机上
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
        //qos=1
        channel.basicQos(1);
        DefaultConsumer consumer = new DefaultConsumer(channel) {

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("send email " + new String(body, Charset.defaultCharset()));
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        boolean autoAck = false;
        channel.basicConsume(QUEUE_NAME, autoAck, consumer);
    }
}


public class Rece2 {
    private final static String QUEUE_NAME = "test_queu_msg";
    private final static String EXCHANGE_NAME = "test_exchange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        // 绑定队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        // 绑定队列到交换机上
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
        //qos=1
        channel.basicQos(1);
        DefaultConsumer consumer = new DefaultConsumer(channel) {

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("send msg " + new String(body, Charset.defaultCharset()));
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        boolean autoAck = false;
        channel.basicConsume(QUEUE_NAME, autoAck, consumer);
    }
}
官方推荐的queue_name

官方希望能够实现,生成唯一名称queue_name,并且一旦断开生产者连接,队列自动删除。

String queueName = channel.queueDeclare().getQueue();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值