springboot與ActiveMQ整合

来源:https://www.cnblogs.com/elvinle/archive/2018/02/24/8457596.html
-Advertisement-
Play Games

前言 很多項目, 都不是一個系統就做完了. 而是好多個系統, 相互協作來完成功能. 那, 系統與系統之間, 不可能完全獨立吧? 如: 在學校所用的管理系統中, 有學生系統, 資產系統, 宿舍系統等等. 當學期結束之後, 是否需要對已經結束的期次進行歸檔操作. 假如歸檔功能在學生系統中, 那點擊歸檔之 ...


前言

   很多項目, 都不是一個系統就做完了. 而是好多個系統, 相互協作來完成功能. 那, 系統與系統之間, 不可能完全獨立吧?

  如: 在學校所用的管理系統中, 有學生系統, 資產系統, 宿舍系統等等. 當學期結束之後, 是否需要對已經結束的期次進行歸檔操作. 假如歸檔功能在學生系統中, 那點擊歸檔之後, 學生是不是還要關心宿舍那邊是否已結束, 學生所領資產是否全都歸還? 

  顯然, 這並不是一個好的方式, 系統之間的耦合性做的太強了, 很不利於系統擴展, 而且, 一步操作, 可能要等很久很久, 才能完成. 用戶可願意等?

  既然同步歸檔不可能了, 那是否有辦法實現非同步歸檔? 非同步歸檔怎麼實現呢?

     我們其實可以通過消息隊列來實現非同步歸檔. 學生這邊點擊歸檔後, 發個消息到隊列中, 其他系統自行去讀取, 然後完成各自系統應該完成的工作.

 

ActiveMQ下載安裝

    下載地址: http://activemq.apache.org/download.html

  安裝過程比較簡單, 在centos中, 解壓出來, 就算是安裝好了

  運行方法: 

 

  運行起來後, 可以通過 ip:8161 來查看是否成功. 

  

點擊紅框中的鏈接, 會出現登錄彈框, 賬號密碼預設都是admin.

 

 

springboot整合activemq

 一. 目錄結構

producer : 消息生產者

consumer-a : 消息消費者

consumer-b : 消息消費者

pom文件:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

 

如果使用pool的話, 就需要在pom中加入以下依賴:

<dependency>
     <groupId>org.apache.activemq</groupId>
     <artifactId>activemq-pool</artifactId>
     <version>5.14.5</version>
</dependency>

 

 二. producer

1. 目錄結構

 

2. yml文件:

server:
  port: 8080
  context-path: /pro
spring:
  activemq:
    user: admin
    password: admin
    broker-url: tcp://192.168.153.129:61616
    pool:
      enabled: true
      max-connections: 10

queueName: publish.queue
topicName: publish.topic

這裡我開啟了連接池, 預設是不開的.

這裡要註意埠, 不是之前的8161.

 

2. 配置文件  ActiveMQConfig 

/**
 * @author: elvin
 */
@Configuration
public class ActiveMQConfig {
    @Value("${queueName}")
    private String queueName;

    @Value("${topicName}")
    private String topicName;

    @Value("${spring.activemq.user}")
    private String usrName;

    @Value("${spring.activemq.password}")
    private  String password;

    @Value("${spring.activemq.broker-url}")
    private  String brokerUrl;

    @Bean
    public Queue queue(){
        return new ActiveMQQueue(queueName);
    }

    @Bean
    public Topic topic(){
        return new ActiveMQTopic(topicName);
    }

    @Bean
    public ActiveMQConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(usrName, password, brokerUrl);
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerQueue(ActiveMQConnectionFactory connectionFactory){
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setConnectionFactory(connectionFactory);
        return bean;
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ActiveMQConnectionFactory connectionFactory){
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
//設置為發佈訂閱方式, 預設情況下使用的生產消費者方式 bean.setPubSubDomain(
true); bean.setConnectionFactory(connectionFactory); return bean; } }

這裡本來不需要配置這麼多的, 但是在consumer中也會用到, 所以就暫時弄一份一樣的, 拷貝一下完事.

 

3. PublishController

/**
 * @author: elvin
 */
@RestController
@RequestMapping("/publish")
public class PublishController {

    @Autowired
    private JmsMessagingTemplate jms;

    @Autowired
    private Queue queue;

    @Autowired
    private Topic topic;

    @RequestMapping("/queue")
    public String queue(){

        for (int i = 0; i < 10 ; i++){
            jms.convertAndSend(queue, "queue"+i);
        }

        return "queue 發送成功";
    }

    @JmsListener(destination = "out.queue")
    public void consumerMsg(String msg){
        System.out.println(msg);
    }

    @RequestMapping("/topic")
    public String topic(){

        for (int i = 0; i < 10 ; i++){
            jms.convertAndSend(topic, "topic"+i);
        }

        return "topic 發送成功";
    }
}

 

 三. consumer 

1. 目錄結構

a,b是一樣的, 只是顯示的信息不同.

 

2. 配置文件

yml配置文件是一樣的, 只是修改了埠和context-path.

ActiveMQConfig文件內容是一樣的.

 

3. listener

/**
 * @author: elvin
 */
@Component
public class QueueListener {

    @JmsListener(destination = "publish.queue", containerFactory = "jmsListenerContainerQueue")
    @SendTo("out.queue")
    public String receive(String text){
        System.out.println("QueueListener: consumer-a 收到一條信息: " + text);
        return "consumer-a received : " + text;
    }
}

SendTo 會將此方法返回的數據, 寫入到 queue : out.queue 中去.

/**
 * @author: elvin
 */
@Component
public class TopicListener {

    @JmsListener(destination = "publish.topic", containerFactory = "jmsListenerContainerTopic")
    public void receive(String text){
        System.out.println("TopicListener: consumer-a 收到一條信息: " + text);
    }
}

這裡通過傳入不同的factory, 來實現發送不同類型的信息.

 

四. 測試

 1. queue測試

瀏覽器中訪問: http://localhost:8080/pro/publish/queue

然後看一下, 控制台, 那些用戶接收到了信息.

從上兩幅圖看的出來, a, b並不能同時接收數據. 這是queue的方式, 點對點.

那我想點對面, 怎麼辦?

 

2. topic測試

瀏覽器訪問頁面: http://localhost:8080/pro/publish/topic

a用戶完全接收到信息了. 再看看b用戶

沒毛病, 也都接收到數據了.

topic預設情況下, 是不會保存數據的, 也就是說, consumer是接收不到之前未接收到的信息.

而queue卻是可以的. 

但是, topic並不是不能實現那個功能, 只要配置一下, 還是可以的.

 


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

-Advertisement-
Play Games
更多相關文章
  • 相關內容: 使用pymysql直接操作mysql 創建表 查看表 修改表 刪除表 插入數據 查看數據 修改數據 刪除數據 使用sqlmary操作mysql 創建表 查看表 修改表 刪除表 插入數據 查看數據 修改數據 刪除數據 首發時間:2018-02-24 23:59 【第一次寫那麼長的博文,若有... ...
  • 在上一篇文章中介紹了自定義標簽的用法,接下來介紹標簽文件的用法啦。 tag file指令 tag file簡介 用tag file的方式,無需編寫標簽處理類和標簽庫描述文件,也可以自定義標簽。tag file從兩個方面簡化了自定義標簽的開發。首先,tag file無須提前編譯,直到第一次調用才會編譯 ...
  • 位置參數 位置參數需與形參一一對應 def test(a,b) #a,b就是位置參數 print(a) print(b) test(1,2) 關鍵字參數 與形參順序無關 def test(x,y) print(x,y) test(x=2,y=3) 位置參數必須在關鍵字參數之前 **kwargs:把N ...
  • 單例模式的定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點! 1、懶漢 2、餓漢 3、雙重校驗鎖 4、枚舉 5、靜態內部類 本文永久更新地址: "https://github.com/nnngu/LearningNotes/blob/master/Java%20Basis/019%20%E ...
  • 前言 為了鞏固MVC的開發模式,下麵就寫一個購物車的小案例.. ①構建開發環境 導入需要用到的開發包 建立程式開發包 ②設計實體 書籍實體 購物車與購物項實體 可能我們會這樣設計購物車 上面的做法是不合適的,試想一下: 如果我要購買兩本相同的書,購物車的頁面上就出現了兩本書,而不是書 2。買三本相同 ...
  • Django中的CBV和FBV 一、 CBV CBV是採用面向對象的方法寫視圖文件。 CBV的執行流程: 瀏覽器向伺服器端發送請求,伺服器端的urls.py根據請求匹配url,找到要執行的視圖類,執行dispatch方法區分出是POST請求還是GET請求,執行views.py對應類中的POST方法或 ...
  • 匿名內部類是內部類的簡寫格式。 定義匿名內部類的前提: 內部類必須是繼承一個類或者實現一個介面。 匿名內部類的格式: 其實匿名內部類就是一個匿名子類對象,就是把定義類和建立對象封裝在一起的一種表現形式,形成的是匿名子類對象。 ...
  • auto關鍵字:1.C++98標準auto關鍵字的作用和C語言的相同,表示自動變數,是關於變數存儲位置的類型飾詞,通常不寫,因為局部變數的預設存儲就是auto 2.C++11標準中auto關鍵字不再表示變數的存儲類型,而是用於類型推導 (2.1)auto的基本用法 (2.2)auto和指針或者引用結 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...