RabbitMQ的基础使用 —— Fanout模式

RabbiteMQ的Fanout模式其实和ActiveMQ的Topic模式比较类似,这里我们就来看一下见到的小例子吧,首先我们看生成者,这里生产者和RabbitMQ的基础使用 —— Direct模式(一)RabbitMQ的基础使用 —— Direct模式(二)中的类似,其中最重要的就是需要将交换器的类型修改为Fanout ,如下:
在这里插入图片描述

public class FanoutProducer {

    //交换器名称
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        //创建连接,连接到RabbitMQ
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        Connection connection = connectionFactory.newConnection();

        //创建信道
        Channel channel = connection.createChannel();
        //创建交换器
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        //定义的业务日志消息级别,即作为路由键使用
        String[] logLevels = {"error", "warn", "info"};
        for (int i = 0; i < logLevels.length; i++) {
            String logLevel = logLevels[i];
            String msg = "Hello RabbitMQ";

            //发布消息,需要参数:交换器、路由键,其中以日志消息级别为路由键
            channel.basicPublish(EXCHANGE_NAME, logLevel, null, msg.getBytes(Charset.forName("UTF-8")));
        }
        channel.close();
        connection.close();
    }
}



然后我们再来看看消费者端,这里我们就用两个消费者来进行测试,一个消费者绑定路由键error,另一个消费者这绑定一个不存在的路由键other,如下:
在这里插入图片描述
在这里插入图片描述

public class ErrorConsumer {

    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        //创建连接,连接到RabbitMQ,与发送端一样
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        Connection connection = connectionFactory.newConnection();

        //创建信道
        Channel channel = connection.createChannel();
        //可不创建,由生产者进行创建
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        String queueName = "logError";  //声明一个队列名称
        String routingKey = "error";    //路由键名称

        //创建一个队列
        channel.queueDeclare(queueName, false, false, false, null);
        //将队列和交换器通过路由键进行绑定
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey);

        //声明了一个消费者
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                StringBuffer buffer = new StringBuffer();
                buffer.append(Thread.currentThread().getName()).append(", ")
                        .append(envelope.getExchange()).append(", ")
                        .append(envelope.getRoutingKey()).append(", ")
                        .append(new String(body, "UTF-8"));
                System.out.println(buffer.toString());
            }
        };
        //消费者正式开始在指定队列上消费消息
        channel.basicConsume(queueName, true, consumer);
    }
}
public class OtherConsumer {

    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        //创建连接,连接到RabbitMQ,与发送端一样
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        Connection connection = connectionFactory.newConnection();

        //创建信道
        Channel channel = connection.createChannel();
        //可不创建,由生产者进行创建
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        String queueName = "logOther";  //声明一个队列名称
        String routingKey = "other";    //路由键名称

        //创建一个队列
        channel.queueDeclare(queueName, false, false, false, null);
        //将队列和交换器通过路由键进行绑定
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey);

        //声明了一个消费者
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                StringBuffer buffer = new StringBuffer();
                buffer.append(Thread.currentThread().getName()).append(", ")
                        .append(envelope.getExchange()).append(", ")
                        .append(envelope.getRoutingKey()).append(", ")
                        .append(new String(body, "UTF-8"));
                System.out.println(buffer.toString());
            }
        };
        //消费者正式开始在指定队列上消费消息
        channel.basicConsume(queueName, true, consumer);
    }
}

按我们预期的效果来看,应该不管我们如何调整生产者和消费者的路由键,都对消息的接受没有影响。下面我们进行测试,如下:
在这里插入图片描述
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章