java嵌入式持久化消息隊列SMQ,改造自FQueue

来源:https://www.cnblogs.com/enenen/archive/2023/02/13/17117260.html
-Advertisement-
Play Games

一、說明 之前項目中一直使用ConcurrentLinkedQueue做為緩衝隊列(主要是單個項目內,單條改批量的場景,多個項目間使用的是rocketmq),雖然用著方便但是是純記憶體的, 如果項目發生異常崩潰記憶體隊列中的數據就會全部丟失(只能從日誌中恢復)。所以一直想找一個簡單高效支持持久化的嵌入式 ...


一、說明

  之前項目中一直使用ConcurrentLinkedQueue做為緩衝隊列(主要是單個項目內,單條改批量的場景,多個項目間使用的是rocketmq),雖然用著方便但是是純記憶體的,

如果項目發生異常崩潰記憶體隊列中的數據就會全部丟失(只能從日誌中恢復)。所以一直想找一個簡單高效支持持久化的嵌入式消息隊列。中間用過activemq的嵌入模式,

雖然是支持持久化了,但是配置起來很繁瑣,用起來也不簡單,性能相比來說也不太行。

  後來偶然發現了FQueue,項目地址:https://github.com/tietang/fqueue 

看了看項目源碼,純java編寫,總共沒幾個類。完全可以改造成我想要的 簡單高效支持持久化的嵌入式消息隊列。

二、改造

  1、因為是要做成嵌入式的,所以memcached協議相關的代碼都刪除了。

  2、預創建文件刪除了,還有一些零零碎碎的改動。(好幾年了,記不清了)。

  3、相較於原代碼,改動最大的就是鎖的部分,FQueue 讀和寫使用的是同一把鎖,

我改成了讀和寫使用不同的鎖,只在文件切換的時候使用同一把鎖。性能大概提示了百分之20左右(本來就很快,錦上添花)。

  4、添加了記憶體隊列,這個主要解決同一個機器創建了大量隊列(上千)時,隊列消息消費較快,因為使用了記憶體映射磁碟(每隔10ms就會調用force()同步磁碟),

頻繁操作磁碟導致磁碟io過高的問題。預設情況下隊列大小超過50時才會寫入持久化隊列。可以在項目啟動時調用SMQ.setting(String dbPath, int logSize, int memoryQueueSize)

進行設置。


三、使用

1、說明

  目前是集成在我個人的工具類項目中的,已發佈到中央倉庫。項目地址:https://github.com/shenbururen/sun-utils

該項目強依賴hutool,算是個人對hutool的個性化的擴展。如果不想依賴該項目,只想單純的使用SMQ,可以將源碼中 cn.sanenen.queue包複製出來,單獨使用。

2、maven引用

<!-- https://mvnrepository.com/artifact/cn.sanenen/sun-utils -->
<dependency>
    <groupId>cn.sanenen</groupId>
    <artifactId>sun-utils</artifactId>
    <version>2.3.0</version>
</dependency>

3、調用

  SMQ使用時只有三個方法,向隊列放入數據、從隊列取出數據、獲取隊列大小(一般只在監控隊列是否積壓時使用,判斷隊列是否有數據,使用獲取隊列數據是否為null進行判斷)。

  我一般是寫一個單獨的類,通過靜態方法調用。

 

/**
 * 本地持久化記憶體隊列
 */
public class MsgQueue {
    private static final String testDataTopic = "testData";

    /**
     * 向隊列放入數據,支持多線程。
     */
    public static void putTestData(TestData msg) {
        SMQ.push(testDataTopic, JSON.toJSONString(msg));
    }

    /**
     * 從隊列取出數據,支持多線程。
     */
    public static TestData getTestData() {
        String poll = SMQ.pop(testDataTopic);
        if (StrUtil.isNotBlank(poll)) {
            return JSON.parseObject(poll, TestData.class);
        }
        return null;
    }

    /**
     * 獲取隊列大小
     */
    public static long getTestDataSize(){
        return SMQ.size(testDataTopic);
    }
}

四、註意事項

  1、預設會在項目目錄下生成一個smq的文件夾用來存放隊列數據。同一個smq的文件夾同時只可被一個項目使用。

  2、SMQ.setting(String dbPath, int logSize, int memoryQueueSize) 

    dbPath文件存儲目錄,預設是smq,會在項目目錄下創建一個smq的目錄。(還沒測試過絕對路徑)。

 

    logSize屬性只可以在項目最開始時設置,之後不可以再設置不同的值。(也可以將生成的smq文件夾刪除後重新啟動進行設置)。

    memoryQueueSize是記憶體隊列大小,預設是50,隊列數據積壓超過memoryQueueSize後才會寫入持久化隊列。(目前memoryQueueSize為0時還是會創建記憶體隊列,這裡之後會優化,不影響使用。)

項目使用了addShutdownHook,會在項目關閉時將記憶體隊列消息寫入持久化隊列。結束項目時使用kill -15  不要用 -9。否則可能造成消息丟失。

    建議都使用預設的,也就是不要調用這個方法。避免調用出現問題。

  3、最好使用在不是要求百分百消息不丟失的場景。(在項目異常停止、伺服器停電關機時,有概率丟失消息。)

  4、目前已經使用兩年多。

 


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

-Advertisement-
Play Games
更多相關文章
  • 回顧第一篇文章中談到的組件庫的幾個方面,只剩下最後的、也是最重要的組件庫的打包構建、本地發佈、遠程發佈了。 1 組件庫構建 組件庫的入口是 packages/yyg-demo-ui,構建組件庫有兩個步驟: 添加 TypeScript 的配置文件: tsconfig.json 添加 vite.conf ...
  • 任務平臺是科技內各業務方開展互動玩法的中心化平臺,支撐科技內拉新、促活、交易等業務場景,包含基礎任務、基於任務的通用活動玩法和業務投放能力。提供了任務玩法的創建、投放、曝光、完成等全生命周期的精細化管理,打造了基於任務的裂變、時間軸等通用活動玩法的規則化運營,致力於提升在多場景、多玩法、多頻次的業務... ...
  • 電商網站Web自動化測試實戰( 編寫京東搜索腳本) 1,打開京東頁 京東首頁地址:https://www.jd.com/,故進入京東首頁如下: 2,打開瀏覽器開發者模式 定位元素前需先打開瀏覽器開發者模式,查看頁面源碼 例-打開chrome開發者模式: windows:快捷鍵F12 Mac ios ...
  • 《Terraform 101 從入門到實踐》這本小冊在南瓜慢說官方網站和GitHub兩個地方同步更新,書中的示例代碼也是放在GitHub上,方便大家參考查看。 簡介 Azure是微軟的公有雲,它提供了一些免費的資源,具體可以查看: https://azure.microsoft.com/en-us/ ...
  • 譯者:kefate 原文:https://github.com/google/guice/wiki/Overview 大家好,我是kefate。今天開始我將會把Google Guice的官方文檔陸續翻譯一遍,水平有限,若有翻譯不妥之處,還望各位不吝指出。OK,話不多說,下麵開始今天的正文~ Guic ...
  • ioc,Inversion of Control(控制反轉),是Spring中的一種設計思想而非技術。 我們可以從4個方面理解ioc: ①誰控制誰? ——Ioc容器控制對象。 ②控制了什麼? ——Ioc容器控制了獲取對象及其外部資源。 ③為什麼是反轉? ——傳統的javaSE技術是手動new對象的, ...
  • 這篇文章主要描述分散式系統中的單體調度機制,它是指一個集群中只有一個節點運行調度進程,並介紹Google Borg的單體調度設計思路。 ...
  • SpringMVC底層機制簡單實現-04 https://github.com/liyuelian/springmvc-demo.git 8.任務7-完成簡單視圖解析 功能說明:通過目標方法返回的 String,轉發或重定向到指定頁面 8.1分析 原生的 SpringMVC 使用視圖解析器來對 Ha ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...