Home ActiveMQ 5 Shared File System Master Slave
Post
Cancel

ActiveMQ 5 Shared File System Master Slave

ActiveMQ 5 在 High Availability (HA) 上分成兩種角色: masterslave ,類似 Active-Standby mode。在一般情況只會有 master 處理 Request,slave 待命,只有當 master 異常時,slave 才會接手這些動作。

一般 ActiveMQ 都是把資料存在記憶體裡面,但是當 Broker 掛掉後,記憶體裡存放的 Message 會消失,因此在 HA 的概念就是要想辦法把 Message 變成 Persistent Data 存在 Disk,然後當 Broker 恢復時或是其他 Broker 接手時,可以直接存取這個 Persistent Data 來接手處理 Message。

ActiveMQ 5 HA 分成兩種方式:

本篇文章主要會探討的是 ActiveMQ 5 的 Shared File System Master Slave 模式。

Shared File System Master Slave Introduction

這個模式是會將 ActiveMQ 的 Persistent Data (Status 或 Message) 儲存在 Shared File System (如 NFS 或是 SAN),再讓其他 ActiveMQ 掛載 Shared File System,讓全部 ActiveMQ 節點共同擁有這些資料。

在開始實作前,先介紹一下運作機制。

ActiveMQ 可以在 activemq.xmlpersistenceAdapter 啟用 Local Database - KahaDB 來儲存 Persistent Data,ActiveMQ 會把 Message 存成 Log 檔存放在 Broker Local 的 KahaDB 目錄裡,預設都不改設定的話 KahaDB 位置為 ${activemq.data}/kahadb 也就是 ActiveMQ 目錄底下的 data/kahadb

1
2
3
        <persistenceAdapter>
            <kahaDB directory="${activemq.data}/kahadb"/>
        </persistenceAdapter>

而在 Shared File System Master Slave 模式下,會把 Shared File System Volume 掛載到 KahaDB 目錄裡,如此一來 Master 跟所有 Slave ActiveMQ 節點都會取得同一個 KahaDB 資料,且這種方式會整合 Lock 機制,先搶到存取權的節點將會變成 Master,而其他結點就會變成 Slave, Slave 狀態的節點大部分服務都不會啟動,只會啟動一個很簡單的 Java 檔,定期檢查 KahaDB 是否已經被 Release,如有被 Release,就會啟動全部服務搶先變成 Master。

  1. 啟用時,只會有一台 Master 存在,其他搶輸的為 Slave (在此 Database1 為 KahaDB)

  2. 當 Master 異常並 Release KahaDB 後,其他 Slave 會爭奪變成新的 Master,接手原本的工作

圖片來源: ActiveMQ - The Failover Transport

在這種模式下只能有一個 Master,但可以有多個 Slave (1~N)。

Implement

以下為環境資訊:

  • Broker A Node
    • 192.168.89.131:61616
    • ActiveMQ 5.16.4
    • Ubuntu 20.04 LTS
    • JMS Protocol
  • Broker B Node
    • 192.168.89.132:61616
    • ActiveMQ 5.16.4
    • Ubuntu 20.04 LTS
    • JMS Protocol
  • Broker C Node
    • 192.168.89.133:61616
    • ActiveMQ 5.16.4
    • Ubuntu 20.04 LTS
    • JMS Protocol
  • NFS Server (192.168.89.134)

如果要用 NFS 要用 NFSv4 不要用 NFSv3 會有問題,可查看 Official - Shared File System Master Slave

NFS Server 建置方式有相當多種,可以參考 Ubuntu 20.04 中配置NFS服務 ,在此不特別闡述

  1. 下載 ActiveMQ 5.16.4
    1
    2
    3
    
    $ wget https://archive.apache.org/dist/activemq/5.16.4/apache-activemq-5.16.4-bin.tar.gz
    $ tar zxvf apache-activemq-5.16.4-bin.tar.gz
    $ cd apache-activemq-5.16.4
    
  2. 三台 Broker Node 都建立一個 /mnt/KahaDB 目錄並掛載 NFS Volume,這個目錄就是用來存放 KahaDB Data。
    1
    2
    
    $ mmkdir -p /mnt/kahaDB
    $ mount -t nfs4 -o proto=tcp,port=2049 192.168.89.134:/nfs /mnt/kahaDB/
    
  3. 接著修改三台 activemq.xml,設定 kahaDB 目錄位置。
    1
    
    $ vim apache-activemq-5.16.4/conf/activemq.xml
    

    persistenceAdapter 改成如下

    1
    2
    3
    
         <persistenceAdapter>
             <kahaDB directory="/mnt/kahaDB"/>
         </persistenceAdapter>
    
  4. 接著就可以啟動三台 ActiveMQ Broker。
    1
    2
    
    $ cd apache-activemq-5.16.4/bin/
    $ ./activemq start
    
  5. 啟動後可以發現只有 Broker C 真正有啟動服務 (8161 port, 61616 port),Broker A 跟 Broker B 都只有啟動一隻 java 程式而已,表示 Broker C 為 Master,其他兩台為 Slave。
    Broker A Broker B Broker C

  6. 查看 Broker A 跟 Broker B Log (apache-activemq-5.16.3/data/acrivemq.log),可以發現該台 Broker 為 Slave Mode。
    1
    2
    3
    
    2022-01-10 08:34:29,383 | INFO  | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1@7cc0cdad: startup date [Mon Jan 10 08:34:29 UTC 2022]; root of context hierarchy | org.apache.activemq.xbean.XBeanBrokerFactory$1 | main
    2022-01-10 08:34:31,638 | INFO  | Using Persistence Adapter: KahaDBPersistenceAdapter[/mnt/kahaDB] | org.apache.activemq.broker.BrokerService | main
    2022-01-10 08:34:31,667 | INFO  | Database /mnt/kahaDB/lock is locked by another server. This broker is now in slave mode waiting a lock to be acquired | org.apache.activemq.store.SharedFileLocker | main
    
  7. 接著在 Producer 及 Consumer 設定 Failover Transport,這樣 Producer/Consumer 就會自動連上可以使用的 ActiveMQ,並且在 ActiveMQ 異常時,自動 Failover 切換連線到其他台。在此 HA 模式下,由於只有 Broker C 目前是有啟用 61616 port 的,因此只會連到 Broker C。
    1
    2
    3
    
    ...
     ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("failover:(tcp://192.168.89.131:61616,tcp://192.168.89.132:61616,tcp://192.168.89.133:61616)");
    ...
    

    Client 程式範例可以參考 Cross Language Clients

  8. 完成後設定後,可以測試執行 apache-activemq-5.16.4/examples/openwire/java 目錄裡的範例程式傳送 Message (1000 筆),這時 Client 會連到 Broker C。
    1
    
    $ java -cp target/openwire-example-0.1-SNAPSHOT.jar example.Publisher
    

    可以看到 Broker C 裡面有 1000 筆 Message

  9. 接著執行 Consumer 程式,會連到 Broker C,然後開始取資料
    1
    
    $ java -cp target/openwire-example-0.1-SNAPSHOT.jar example.Listener
    

  10. 取到一半把 Broker C 關閉掉,模擬異常
    1
    
    ./activemq stop
    

    如果 Consumer 接收 Message 過快的話,可以試著在程式加 sleep 機制,讓他放慢速度,比較好測試

  11. 大約等幾秒可以看到 Broker B 服務啟動了並接手了工作,變成 Master,然後 Consumer 會改成連至 Broker B,然後繼續從 Queue 取沒取完的 Message。

  12. 完成。

Reference

文章內容的轉載、重製、發佈,請註明出處: https://pohsienshih.github.io

This post is licensed under CC BY 4.0 by the author.