RabbitMQ廣播模式(動態生成queue)

RabbitMQ的廣播機制和ActiveMQ有所不同。
先來梳理下RabbitMQ中消息從產生到消費的流程吧:
在這裏插入圖片描述
而exchange 存在多種類型,這裏就只說廣播模式(fanout)了。在廣播模式中,一個exchange對應多個queue,會向每個queue都發送信息,然後不同的queue再由其對應的消費者消費信息,即完成了廣播。
因爲廣播模式中不關注routingkey和queue,只需要queue的queue name唯一即可,所以這裏把routingkey移出來了,實際上還是會經過的哦。

在這裏插入圖片描述

1.新建一個spring boot 項目並引入官方的amqp包

<dependency>
	<groupId>org.springframework.amqp</groupId>
	<artifactId>spring-rabbit</artifactId>
</dependency>

2.添加RabbitMQ連接參數

spring.rabbitmq.host=xx
spring.rabbitmq.port=5672
spring.rabbitmq.username=xx
spring.rabbitmq.password=xx

3.創建生產者

同時添加一個配置參數rabbit.exchange,用來動態指定exchange(比如使用apollo或者spring cloud config)
增加配置參數

rabbit.exchange=testExchange

增加生產者

@Component
public class Producer {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Value("${rabbit.exchange}")
    private String exchange;

    public void sendInfo(){
        Message message = new Message("123".getBytes(),new MessageProperties());
        rabbitTemplate.send(exchange,"",message);
    }
}

4.動態創建queue和消費者

因爲需要執行createQueue方法才能生成一個queue和消費者,所以這裏先用@Component指定掃描當前類,再用@PostConstruct指定掃描時執行該方法。
因爲創建的queue是臨時queue,當消費者消失時,該queue就會自動刪除,因爲創建queue也是由rabbitMQ自行生成的,所以queue name一定是唯一的。這樣在集羣部署時,就可以做到即開即用了,就算關閉了服務,對應的queue也會自動消失。

@Component
public class Consumer {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Value("${rabbit.exchange}")
    private String exchange;

    @PostConstruct
    public void createQueue(){
        Channel channel = rabbitTemplate.getConnectionFactory().createConnection().createChannel(true);

        try{
            /**
             * 與生產者使用同一個交換機
             */
            channel.exchangeDeclare(exchange, "fanout",true);
            /**
             * 獲取一個隨機的隊列名稱,使用默認方式,產生的隊列爲臨時隊列,在沒有消費者時將會自動刪除
             */
            String queueName = channel.queueDeclare().getQueue();

            /**
             * 關聯 exchange 和 queue ,因爲是廣播無需指定routekey,routingKey設置爲空字符串
             */
            // channel.queueBind(queue, exchange, routingKey)
            channel.queueBind(queueName, exchange, "");

            com.rabbitmq.client.Consumer consumer = 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");

                    if(StringUtils.isEmpty(message)){
                        return;
                    }

                    /**
                     * 對信息做操作
                     */
                }

            };
            //true 自動回覆ack
            channel.basicConsume(queueName, true, consumer);
        }catch (Exception ex){
        }
    }
}

5.手動在RabbitMQ控制界面創建exchange

如下圖選擇廣播模式,並且爲永久exchange,如果要設置臨時exchange的話要修改4中的如下語句最後一個參數爲false

channel.exchangeDeclare(exchange, "fanout",true);

在這裏插入圖片描述

6.啓動項目,測試

Consumer中打個斷點,就能看到在啓動時調用createQueue後所產生的隊列名
在這裏插入圖片描述
到RabbitMQ控制檯上搜索下,確實存在
在這裏插入圖片描述
點開看下對應的exchange
在這裏插入圖片描述
完全OK,發送條信息試下,也能夠接收到
在這裏插入圖片描述
在這裏插入圖片描述
可以試下再重複第4步,再建一個queue,或者再起一個項目,你會發現兩個消費者都能接收到信息。

然後我們把項目關閉,看看queue還在不在,明顯已經木有了。
在這裏插入圖片描述

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