Spring Boot 配置多源的 RabbitMQ

来源:https://www.cnblogs.com/innerpeacez/archive/2019/07/19/11213009.html
-Advertisement-
Play Games

簡介 是開發中很平常的中間件,本文講述的是怎麼在一個 項目中配置多源的 ,這裡不過多的講解 的相關知識點。如果你也有遇到需要往多個 中發送消息的需求,希望本文可以幫助到你。 環境 rabbitmq 3.7.12 spring boot 2.1.6.RELEASE 當然軟體的版本不是硬性要求,只是我使 ...


簡介

MQ 是開發中很平常的中間件,本文講述的是怎麼在一個Spring Boot項目中配置多源的RabbitMQ,這裡不過多的講解RabbitMQ的相關知識點。如果你也有遇到需要往多個RabbitMQ中發送消息的需求,希望本文可以幫助到你。

環境

  • rabbitmq 3.7.12
  • spring boot 2.1.6.RELEASE

當然軟體的版本不是硬性要求,只是我使用的環境而已,唯一的要求是需要啟動兩個RabbitMQ,我這邊是在kubernetes集群中使用helm官方提供的charts包快速啟動的兩個rabbitmq-ha高可用rabbitmq集群。

想要瞭解 kubernetes或者helm,可以參看以下 github倉庫:

SpringBoot中配置兩個RabbitMQ源

在springboot 中配置單個RabbitMQ是極其簡單的,我們只需要使用Springboot為我們自動裝配的RabbitMQ相關的配置就可以了。但是需要配置多個源時,第二個及其以上的就需要單獨配置了,這裡我使用的都是單獨配置的。

代碼:
/**
 * @author innerpeacez
 * @since 2019/3/11
 */
@Data
public abstract class AbstractRabbitConfiguration {

    protected String host;
    protected int port;
    protected String username;
    protected String password;

    protected ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }
}

第一個源的配置代碼

package com.zhw.study.springbootmultirabbitmq.config;

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @author innerpeacez
 * @since 2019/3/8
 */

@Configuration
@ConfigurationProperties("spring.rabbitmq.first")
public class FirstRabbitConfiguration extends AbstractRabbitConfiguration {

    @Bean(name = "firstConnectionFactory")
    @Primary
    public ConnectionFactory firstConnectionFactory() {
        return super.connectionFactory();
    }

    @Bean(name = "firstRabbitTemplate")
    @Primary
    public RabbitTemplate firstRabbitTemplate(@Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean(name = "firstFactory")
    public SimpleRabbitListenerContainerFactory firstFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                             @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(value = "firstRabbitAdmin")
    public RabbitAdmin firstRabbitAdmin(@Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }
}

第二個源的配置代碼

package com.zhw.study.springbootmultirabbitmq.config;

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author innerpeacez
 * @since 2019/3/8
 */

@Configuration
@ConfigurationProperties("spring.rabbitmq.second")
public class SecondRabbitConfiguration extends AbstractRabbitConfiguration {

    @Bean(name = "secondConnectionFactory")
    public ConnectionFactory secondConnectionFactory() {
        return super.connectionFactory();
    }

    @Bean(name = "secondRabbitTemplate")
    public RabbitTemplate secondRabbitTemplate(@Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean(name = "secondFactory")
    public SimpleRabbitListenerContainerFactory secondFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                             @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean(value = "secondRabbitAdmin")
    public RabbitAdmin secondRabbitAdmin(@Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }
}

配置信息

spring:
  application:
    name: multi-rabbitmq
  rabbitmq:
    first:
      host: 192.168.10.76
      port: 30509
      username: admin
      password: 123456
    second:
      host: 192.168.10.76
      port: 31938
      username: admin
      password: 123456
測試

這樣我們的兩個RabbitMQ源就配置好了,接下來我們進行測試使用,為了方便使用,我寫了一個MultiRabbitTemplate.class 方便我們使用不同的源。

/**
 * @author innerpeacez
 * @since 2019/3/8
 */
@Component
public abstract class MultiRabbitTemplate {

    @Autowired
    @Qualifier(value = "firstRabbitTemplate")
    public AmqpTemplate firstRabbitTemplate;

    @Autowired
    @Qualifier(value = "secondRabbitTemplate")
    public AmqpTemplate secondRabbitTemplate;
}

第一個消息發送者類 TestFirstSender.class

/**
 * @author innerpeacez
 * @since 2019/3/11
 */
@Component
@Slf4j
public class TestFirstSender extends MultiRabbitTemplate implements MessageSender {

    @Override
    public void send(Object msg) {
        log.info("rabbitmq1 , msg: {}", msg);
        firstRabbitTemplate.convertAndSend("rabbitmq1", msg);
    }

    public void rabbitmq1sender() {
        this.send("innerpeacez1");
    }
}

第二個消息發送者類 TestSecondSender.class

/**
 * @author innerpeacez
 * @since 2019/3/11
 */
@Component
@Slf4j
public class TestSecondSender extends MultiRabbitTemplate implements MessageSender {

    @Override
    public void send(Object msg) {
        log.info("rabbitmq2 , msg: {}", msg);
        secondRabbitTemplate.convertAndSend("rabbitmq2", msg);
    }

    public void rabbitmq2sender() {
        this.send("innerpeacez2");
    }
}

動態創建Queue的消費者

/**
 * @author innerpeacez
 * @since 2019/3/11
 */

@Slf4j
@Component
public class TestFirstConsumer implements MessageConsumer {

    @Override
    @RabbitListener(bindings = @QueueBinding(value = @Queue("rabbitmq1")
            , exchange = @Exchange("rabbitmq1")
            , key = "rabbitmq1")
            , containerFactory = "firstFactory")
    public void receive(Object obj) {
        log.info("rabbitmq1 , {}", obj);
    }

}
/**
 * @author innerpeacez
 * @since 2019/3/11
 */

@Slf4j
@Component
public class TestSecondConsumer implements MessageConsumer {

    @Override
    @RabbitListener(bindings = @QueueBinding(value = @Queue("rabbitmq2")
            , exchange = @Exchange("rabbitmq2")
            , key = "rabbitmq2")
            , containerFactory = "secondFactory")
    public void receive(Object obj) {
        log.info("rabbitmq2 , {}", obj);
    }

}

測試類

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringBootMultiRabbitmqApplicationTests extends MultiRabbitTemplate {

    @Autowired
    private TestFirstSender firstSender;
    @Autowired
    private TestSecondSender secondSender;

    /**
     * 一百個線程向 First Rabbitmq 的 rabbitmq1 queue中發送一百條消息
     */
    @Test
    public void testFirstSender() {
        for (int i = 0; i < 100; i++) {
            new Thread(() ->
                    firstSender.rabbitmq1sender()
            ).start();
        }
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 一百個線程向 Second Rabbitmq 的 rabbitmq2 queue中發送一百條消息
     */
    @Test
    public void testSecondSender() {
        for (int i = 0; i < 100; i++) {
            new Thread(() ->
                    secondSender.rabbitmq2sender()
            ).start();
        }
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

測試結果:

總結

這樣配置好之後我們就可向兩個RabbitMQ中發送消息啦。這裡只配置了兩個源,當然如果你需要更多的源,僅僅只需要配置*RabbitConfiguration.class就可以啦。本文沒有多說關於RabbitMQ的相關知識,如果未使用過需要自己瞭解一下相關知識。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • LinuxShell腳本——選擇結構 摘要:本文主要學習了Shell腳本中的選擇結構。 if-else語句 基本語法 最簡單的用法就是只使用if語句,它的語法格式為: 如果將if和then寫在一行,則需要在then前面添加“;”: 如果有兩個分支,就可以使用if-else語句,它的格式為: Shel ...
  • 環境準備系統: 主機兩台,分別是docker私有庫伺服器(IP 192.168.121.121)和用戶開發機(IP 192.168.121.122),開發機從私有庫伺服器拉取鏡像。 1、配置軟體源並安裝安裝docker兩台主機安裝docker 2、搭建私有鏡像倉庫登陸私有庫伺服器 創建docker管 ...
  • LinuxShell腳本——變數和數據類型 摘要:本文主要學習了Shell腳本中的變數和數據類型。 變數 定義變數的語法 定義變數時,變數名和變數值之間使用“=”分隔,並且等號兩邊不能有空格: 變數名規則 變數名的定義必須遵循以下規則: 使用變數 使用一個定義過的變數,只要在變數名前面加美元符號即可 ...
  • 用戶身份與文件許可權 用戶身份與能力 Linux系統的管理員之所以是root,並不是因為它的名字叫root,而是因為該用戶的身份號碼即UID(User IDentification)的數值為0。 在Linux系統中,UID就相當於我們的身份證號碼一樣具有唯一性,因此可通過用戶的UID值來判斷用戶身份。 ...
  • 如果ping功能變數名稱的時候出現ping:unknown host xxx.xxx 但是ping IP地址的時候可以通的話 可知是dns伺服器沒有配置好, 查看一下配置文件/etc/resolv.conf,裡面是否有nameserver xxx.xxx.xxx.xxx, 如果沒有,文本內容中添加: nam ...
  • shell腳本&定時任務 編寫Shell腳本 可以將Shell終端解釋器當作人與電腦硬體之間的“翻譯官”。 Shell腳本命令的工作方式有兩種:互動式和批處理。 互動式(Interactive):用戶每輸入一條命令就立即執行。 批處理(Batch):由用戶事先編寫好一個完整的Shell腳本,She ...
  • CentOS 6.5安裝aria2 由於yum install aria2無法找到安裝包,試了好幾個源,都找不到,於是自己找了一些地址: 1、下載安裝包: # wget http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el6/en/x86_64/rpmf ...
  • 一、準備 將下載好的jdk以及scratch鏡像放在同一文件夾下:這裡放在linux:2.0 二、導入scratch鏡像 三、創建dockerfile文件,並編寫 文件內容如下: 四、創建鏡像名為Linux:2.0 五、運行鏡像 查看java是否安裝好 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...