欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring項(xiàng)目集成RabbitMQ及自動(dòng)創(chuàng)建隊(duì)列

 更新時(shí)間:2024年02月02日 16:16:48   作者:coder_xhp  
這篇文章主要介紹了Spring項(xiàng)目集成RabbitMQ及自動(dòng)創(chuàng)建隊(duì)列,本文內(nèi)容分別在Spring(V5.2.6)和Spring Boot(V2.5.14)兩個(gè)項(xiàng)目中經(jīng)過了驗(yàn)證,需要的朋友可以參考下

簡(jiǎn)單記錄Spring項(xiàng)目集成RabbitMQ的過程,重點(diǎn)記錄生產(chǎn)者項(xiàng)目自動(dòng)創(chuàng)建隊(duì)列的操作,因該問題給項(xiàng)目帶來很多麻煩。

本文內(nèi)容分別在Spring(V5.2.6)和Spring Boot(V2.5.14)兩個(gè)項(xiàng)目中經(jīng)過了驗(yàn)證,下述示例代碼來自于SpringBoot項(xiàng)目,遷移到Spring項(xiàng)目中需稍微調(diào)整。

一、Spring Boot集成RabbitMQ

1. 在Maven中加入依賴

Spring項(xiàng)目和SpringBoot項(xiàng)目的依賴有區(qū)別,按需引入:

<!-- Spring Boot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- Spring -->
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

2. 在Spring配置文件增加配置項(xiàng)

spring:
    rabbitmq:
    	# 基礎(chǔ)項(xiàng)
        host: 192.168.1.123
        port: 5672
        username: admin
        password: admin
        # virtualhost需要提前在MQ的Web管理界面里手動(dòng)創(chuàng)建,或者配置默認(rèn)host"/"
        virtual-host: /test
        # 生產(chǎn)者
        #確認(rèn)消息已發(fā)送到交換機(jī)(Exchange)
        publisher-confirm-type: correlated
        #確認(rèn)消息已發(fā)送到隊(duì)列(Queue)
        publisher-returns: true
        # 消費(fèi)者
        listener:
	    	type: simple
    		simple:
		        default-requeue-rejected: false
		        acknowledge-mode: auto #確認(rèn)模式
		        prefetch: 1 #限制每次發(fā)送一條數(shù)據(jù)
		        max-concurrency: 1 #啟動(dòng)消費(fèi)者最大數(shù)量
		        concurrency: 1 #同一個(gè)隊(duì)列啟動(dòng)幾個(gè)消費(fèi)者
		        retry:
		          enabled: true #是否支持重試

說明:這里僅按照現(xiàn)有項(xiàng)目的配置列出,在實(shí)際的項(xiàng)目中,還是需要根據(jù)自身實(shí)際情況做出調(diào)整。

3. 編寫生產(chǎn)者代碼

3.1 創(chuàng)建RabbitMQ配置類:

@Configuration
public class RabbitMQConfig {
    //queue
    public static final String WORK_QUEUE = "test.queue";
    //exchange
    public static final String WORK_DIRECTEXCHANGE = "test.directExchange";
    //routing
    public static final String WORK_DIRECTROUTING = "test.directRouting";
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }
    // Queue
    @Bean
    public Queue directQueue() {
        Map<String, Object> argsMap = new HashMap<String, Object>();
        argsMap.put("x-max-priority", 5);
        Queue queue = new Queue(WORK_QUEUE, true, false, false, argsMap);
        return queue;
    }
    //Direct交換機(jī)
    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(WORK_DIRECTEXCHANGE, true, false);
    }
    //綁定
    @Bean
    Binding bindingDirect() {
        return BindingBuilder.bind(directQueue()).to(directExchange()).with(WORK_DIRECTROUTING);
    }
}

3.2 編寫發(fā)送消息工具類:

@Component
public class RabbitMQUtils {
    private static RabbitTemplate rabbitTemplate;
    @Autowired
    public RabbitMQUtils(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }
    public static void sendMsg(String msg) throws AmqpException {
        try {
            rabbitTemplate.convertAndSend(RabbitMQConfig.WORK_DIRECTEXCHANGE, RabbitMQConfig.WORK_DIRECTROUTING, msg);
        } catch (AmqpException e) {
            throw new AmqpException ("RabbitMQ發(fā)送消息異常", e);
        }
    }
}

3.3 編寫單元測(cè)試,測(cè)試發(fā)送消息結(jié)果。

4. 編寫消費(fèi)者代碼

4.1 編寫監(jiān)聽器:

@Component
public class RabbitMQListener {
	@RabbitListener(queues = {Constants.WORK_QUEUE})//監(jiān)聽隊(duì)列
	public void listener(String msg, Message message)  {
		System.out.println(msg);
		System.out.println(message.getBody());
	}
}

二、存在的問題

1. 問題描述

實(shí)際項(xiàng)目中,消息的生產(chǎn)者和消費(fèi)者不在同一項(xiàng)目中,如果先啟動(dòng)消費(fèi)者會(huì)因?yàn)闆]有隊(duì)列而啟動(dòng)失敗。

2. 嘗試解決

2.1 方式一:最容易想到的是,在MQ的Web管理界面中手動(dòng)創(chuàng)建隊(duì)列:

  • 該方式在實(shí)際操作是個(gè)不容易的事情,因?yàn)檫€要?jiǎng)?chuàng)建Channel和Exchange,何況發(fā)布的人不一定是開發(fā)的人,溝通繁瑣,極易出錯(cuò),好像程序還是半成品似的;

2.2 方式二:?jiǎn)?dòng)消費(fèi)者項(xiàng)目時(shí),監(jiān)聽器發(fā)現(xiàn)不存在隊(duì)列自動(dòng)創(chuàng)建:

  • “通過@RabbitListener”的參數(shù),確實(shí)可以實(shí)現(xiàn);
  • 但是這種方式在我的項(xiàng)目中出現(xiàn)了新問題,消費(fèi)者項(xiàng)目啟動(dòng)后創(chuàng)建了隊(duì)列,但是生產(chǎn)者發(fā)送消息出錯(cuò),貌似沒有了權(quán)限?
  • 當(dāng)時(shí)因?yàn)轫?xiàng)目工期,并未深究,具體錯(cuò)誤也沒記錄下來;應(yīng)該是自己的代碼有問題;
  • 因此,不能確認(rèn)該方式的可行性,或者具體實(shí)現(xiàn)方式。

2.3 方式三:先啟動(dòng)生產(chǎn)者項(xiàng)目:

  • 因RabbitMQ懶加載模式,所以單純啟動(dòng)項(xiàng)目是不會(huì)創(chuàng)建隊(duì)列的;
  • 因此,最開始的想法是,啟動(dòng)項(xiàng)目后,先發(fā)送一條測(cè)試消息去創(chuàng)建隊(duì)列,項(xiàng)目確實(shí)用該方式使用了一段時(shí)間;
  • 近期在升級(jí)項(xiàng)目時(shí),發(fā)現(xiàn)個(gè)現(xiàn)象,沒有隊(duì)列時(shí)候的第一條消息確實(shí)可以創(chuàng)建隊(duì)列,但是MQ里沒有消息,是空隊(duì)列;
  • 種種問題促使自己重新尋找解決方式,在生產(chǎn)者項(xiàng)目啟動(dòng)后可以自動(dòng)創(chuàng)建隊(duì)列,因此有了本篇文章;
  • 很慚愧,其實(shí)答案一直在,但是自己對(duì)MQ的認(rèn)知一直停留在簡(jiǎn)單使用里,希望有機(jī)會(huì)能深入的學(xué)習(xí)一下吧。

三、生產(chǎn)者項(xiàng)目創(chuàng)建隊(duì)列

1. 在RabbitMQ配置類中加入RabbitAdmin

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

2. 通過RabbitAdmin聲明隊(duì)列,完成隊(duì)列的創(chuàng)建

    @Bean
    public Queue directQueue() {
        Map<String, Object> argsMap = new HashMap<String, Object>();
        argsMap.put("x-max-priority", 5);
        Queue queue = new Queue(WORK_QUEUE, true, false, false, argsMap);
        // 聲明隊(duì)列
        rabbitAdmin.declareQueue(queue);
        return queue;
    }

3. 修改后的完整配置類

@Configuration
public class RabbitMQConfig {
    //queue
    public static final String WORK_QUEUE = "test.queue";
    //exchange
    public static final String WORK_DIRECTEXCHANGE = "test.directExchange";
    //routing
    public static final String WORK_DIRECTROUTING = "test.directRouting";
    @Autowired
    private RabbitAdmin rabbitAdmin;
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }
    @Bean
    public Queue directQueue() {
        Map<String, Object> argsMap = new HashMap<String, Object>();
        argsMap.put("x-max-priority", 5);
        Queue queue = new Queue(WORK_QUEUE, true, false, false, argsMap);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    //Direct交換機(jī)
    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(WORK_DIRECTEXCHANGE, true, false);
    }
    //綁定
    @Bean
    Binding bindingDirect() {
        return BindingBuilder.bind(directQueue()).to(directExchange()).with(WORK_DIRECTROUTING);
    }
}

4. 啟動(dòng)項(xiàng)目,查看隊(duì)列創(chuàng)建情況

經(jīng)過多次測(cè)試,在僅手動(dòng)創(chuàng)建virtual-host的前提下,啟動(dòng)項(xiàng)目,隊(duì)列可以自動(dòng)創(chuàng)建,且發(fā)送/接收消息都正常完成。

到此這篇關(guān)于Spring項(xiàng)目集成RabbitMQ及自動(dòng)創(chuàng)建隊(duì)列的文章就介紹到這了,更多相關(guān)Spring RabbitMQ自動(dòng)創(chuàng)建隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論