ActiveMQ詳細筆記(一)

ActiveMQ的安裝


安裝要求:

部署需要jdk1.5及以上,編譯需要jdk1.5(java5)及以上

Java的環境變量(JAVA_HOME)必須設置,即jdk安裝的目錄,比如c:\Program Files\jsdk.1.6

下載ActiveMQ:http://activemq.apache.org/download.html

解壓,如圖:

目錄結構

運行bin文件夾下的activemq.bat,出現如下圖所示:

運行

驗證是否運行成功:

在瀏覽器中輸入:http://localhost:8161/admin/,出現如下圖所示表示成功:

控制檯

此時,ActiveMQ已經安裝完成了,接下來配置登錄監視控制檯的用戶名和密碼。

打開conf文件夾下的jetty.xml,找到

把authenticate屬性的值改成true即可,重啓activemq.bat,再登錄監視控制檯,就需要輸入密碼了,默認的用戶名和密碼是admin/admin。roles屬性指的是登錄的用戶角色,這些登錄的用戶在jetty-realm.properties配置。

修改web的訪問端口,在jetty.xml找到一下配置,修改8161即可。

ActiveMQ的運行日誌存放在data文件夾下的activemq.log中。

 

Linux和Aix系統下的安裝:

解壓:tar zxvf activemq-x.x.x.tar.gz,進入bin文件夾,運行:./activemq start &,也可以只運行:./activemq console。

驗證方式和安全性配置和windows下的配置一樣。


ActiveMQ消息持久化

在broker中設置屬性persistent=”true”(默認是true),同時發送的消息也應該是persitent類型的。ActiveMQ消息持久化有三種方式:AMQ、KahaDB、JDBC。

1、AMQ

AMQ是一種文件存儲形式,它具有寫入速度快和容易恢復的特點。消息存儲在一個個文件中,文件的默認大小爲32兆,如果一條消息的大小超過了32兆,那麼這個值必須設置大點。當一個存儲文件中的消息已經全部被消費,那麼這個文件將被標識爲可刪除,在下一個清除階段,這個文件被刪除。默認配置如下:

AMQ的屬性:

屬性名稱 默認值 描述
directory activemq-data 消息文件和日誌的存儲目錄
useNIO true 使用NIO協議存儲消息
syncOnWrite false 同步寫到磁盤,這個選項對性能影響非常大
maxFileLength 32mb 一個消息文件的大小
persistentIndex true 消息索引的持久化,如果爲false,那麼索引保存在內存中
maxCheckpointMessageAddSize 4kb 一個事務允許的最大消息量
cleanupInterval 30000 清除操作週期,單位ms
indexBinSize 1024 索引文件緩存頁面數,缺省爲1024,當amq擴充或者縮減存儲時,會鎖定整個broker,導致一定時間的阻塞,所以這個值應該調整到比較大,但是代碼中實現會動態伸縮,調整效果並不理想。
indexKeySize 96 索引key的大小,key是消息ID
indexPageSize 16kb 索引的頁大小
directoryArchive archive 存儲被歸檔的消息文件目錄
archiveDataLogs false 當爲true時,歸檔的消息文件被移到directoryArchive,而不是直接刪除

2、KahaDB

KahaDB是基於文件的本地數據庫儲存形式,雖然沒有AMQ的速度快,但是它具有強擴展性,恢復的時間比AMQ短,從5.4版本之後KahaDB做爲默認的持久化方式。默認配置如下:

KahaDB的屬性:

property name default value Comments
directory activemq-data 消息文件和日誌的存儲目錄
indexWriteBatchSize 1000 一批索引的大小,當要更新的索引量到達這個值時,更新到消息文件中
indexCacheSize 10000 內存中,索引的頁大小
enableIndexWriteAsync false 索引是否異步寫到消息文件中
journalMaxFileLength 32mb 一個消息文件的大小
enableJournalDiskSyncs true 是否講非事務的消息同步寫入到磁盤
cleanupInterval 30000 清除操作週期,單位ms
checkpointInterval 5000 索引寫入到消息文件的週期,單位ms
ignoreMissingJournalfiles false 忽略丟失的消息文件,false,當丟失了消息文件,啓動異常
checkForCorruptJournalFiles false 檢查消息文件是否損壞,true,檢查發現損壞會嘗試修復
checksumJournalFiles false 產生一個checksum,以便能夠檢測journal文件是否損壞。
5.4版本之後有效的屬性:    
archiveDataLogs false 當爲true時,歸檔的消息文件被移到directoryArchive,而不是直接刪除
directoryArchive null 存儲被歸檔的消息文件目錄
databaseLockedWaitDelay 10000 在使用負載時,等待獲得文件鎖的延遲時間,單位ms
maxAsyncJobs 10000 同個生產者產生等待寫入的異步消息最大量
concurrentStoreAndDispatchTopics false 當寫入消息的時候,是否轉發主題消息
concurrentStoreAndDispatchQueues true 當寫入消息的時候,是否轉發隊列消息
5.6版本之後有效的屬性:    
archiveCorruptedIndex false 是否歸檔錯誤的索引

從5.6版本之後,有可能發佈通過多個kahadb持久適配器來實現分佈式目標隊列存儲。什麼時候用呢?如果有一個快速的生產者和消費者,當某一個時刻生產者發生了不規範的消費,那麼有可能產生一條消息被存儲在兩個消息文件中,同時,有些目標隊列是危險的並且要求訪問磁盤。在這種情況下,你應該用通配符來使用mKahaDB。如果目標隊列是分佈的,事務是可以跨越多個消息文件的。

每個KahaDB的實例都可以配置單獨的適配器,如果沒有目標隊列提交給filteredKahaDB,那麼意味着對所有的隊列有效。如果一個隊列沒有對應的適配器,那麼將會拋出一個異常。配置如下:

如果filteredKahaDB的perDestination屬性設置爲true,那麼匹配的目標隊列將會得到自己對應的KahaDB實例。配置如下:

Java
1
2
3
4
5
6
7
8
9
10
11
12
<persistenceAdapter>
  <mKahaDBdirectory="${activemq.base}/data/kahadb">
    <filteredPersistenceAdapters>
      <!--kahaDB per destinations-->
      <filteredKahaDBperDestination="true">
        <persistenceAdapter>
          <kahaDBjournalMaxFileLength="32mb"/>
        </persistenceAdapter>
      </filteredKahaDB>
    </filteredPersistenceAdapters>
  </mKahaDB>
</persistenceAdapter>

3、JDBC

配置JDBC適配器:

dataSource指定持久化數據庫的bean,createTablesOnStartup是否在啓動的時候創建數據表,默認值是true,這樣每次啓動都會去創建數據表了,一般是第一次啓動的時候設置爲true,之後改成false。

MYSQL持久化bean

SQL Server持久化bean

Oracle持久化bean

DB2持久化bean

Java
1
2
3
4
5
6
7
8
  <beanid="db2-ds"class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">
      <propertyname="driverClassName"value="com.ibm.db2.jcc.DB2Driver"/>
      <propertyname="url"value="jdbc:db2://hndb02.bf.ctc.com:50002/activemq"/>
      <propertyname="username"value="activemq"/>
      <propertyname="password"value="activemq"/>
      <propertyname="maxActive"value="200"/>
      <propertyname="poolPreparedStatements"value="true"/>
  </bean>

ActiveMQ消息發送與接收

配置完了持久化之後,我們就可以使用代碼來發送和接收ActiveMQ中的消息了,我這裏配置的持久化是KahaDB。
需要導入的jar包:
activemq所需的jar包
一段發送消息的代碼:

執行了上面的發送方法之後,在ActiveMQ的監視控制可以看到有一個test隊列,並且有一條消息,如圖:

點擊隊列名test,然後點擊消息ID即可查看消息內容,如圖:

如果DeliveryMode沒有設置或者設置爲NON_PERSISTENT,那麼重啓MQ之後消息就會丟失。
一段接收消息的代碼:

執行了上面的接收方法之後,在ActiveMQ的監視控制可以看到test隊列的消息已經被消費了,如圖:

這裏的代碼只是測試用,在正式開發中一般與Spring結合使用jmsTemplate來發送消息,現實JMS的MessageListener來監聽消息。


ActiveMQ配置安全性

監視ActiveMQ的方式有多種,在第一部分中已經說到了Web監視控制檯,設置登錄用戶名和密碼,這裏再說一下JMX監控。運行了ActiveMQ之後,再運行jdk自帶的jconsole即可以看到ActiveMQ的進程,如圖:點擊連接之後就可以看到ActiveMQ的運行情況。默認情況下是不需要用戶名和口令的,修改activemq.bat,找到

修改成

Linux下的找到:

去掉註釋即可。
重啓ActiveMQ之後,在用jconsole連接就需要輸入用戶名和密碼,jmx.access文件配置用戶的訪問權限readonly和readwrite,admin readwrite表示用戶admin具有讀寫權限。Jmx.password文件配置用戶的密碼,admin activemq 表示admin用戶的密碼是activemq。

除了監視臺可以設置用戶名和密碼之後,ActiveMQ也可以對各個主題和隊列設置用戶名和密碼,配置如下:

simpleAuthenticationPlugin中設置用戶名、密碼和羣組,authorizationPlugin設置主題和隊列的訪問羣組,“>”表示所有的主題或者隊列。上面的配置中添加了一個testUser,屬於羣組testGroup,同時設置test這個隊列的訪問讀寫權限爲testGroup,當然admins也可以訪問的,因爲admins是對所有的隊列都有訪問權限。將第三部分代碼中的設置用戶名和密碼改成剛剛添加的用戶testUser,如果密碼不正確,將會拋出User name or password is invalid.異常,如果testUser所屬的羣組不能訪問test隊列,那麼會拋出User guest is not authorized to write to: queue://test異常。需要注意的是所有的羣組都需要對以ActiveMQ.Advisory爲前綴的主題具有訪問權限。

ActiveMQ負載均衡

ActiveMQ可以實現多個mq之間進行路由,假設有兩個mq,分別爲brokerA和brokerB,當有一條消息發送到brokerA的隊列test中,有一個客戶端連接到brokerB上,並且要求獲取test隊列的消息時,brokerA中隊列test的消息就會路由到brokerB上,反之brokerB的消息也會路由到brokerA。
靜態路由配置,brokerA不需要特別的配置,brokerB需要配置networkConnectors節點,具體配置如下:

靜態路由支持failover,如:static:failover://(tcp://host1:61616,tcp://host2:61616)。
動態路由配置,每個mq都需要配置如下:

注意:networkConnectors需要配置在persistenceAdapter之前。
重啓ActiveMQ,可以看到brokerA的日誌如圖:


networkConnector的屬性請參照:http://activemq.apache.org/networks-of-brokers.html

ActiveMQ主備配置

ActiveMQ的主備有三種方式:純Master/Slave、文件共享方式、數據庫共享方式。
1、純Master/Slave
這種方式的主備不需要對Master Broker做特殊的配置,只要在Slave Broker中指定他的Master就可以了,指定Master有兩種方式,最簡單的配置就是在broker節點中添加masterConnectorURI=”tcp://localhost:61616″即可,還有一種方式就是添加一個services節點,可以指定連接的用戶名和密碼,配置如下:

純Master/Slave只允許一個Slave連接到Master上面,也就是說只能有2臺MQ做集羣,同時當Master掛了之後需要停止Slave來恢復負載。
2、數據庫共享方式
這種方式的主備採用數據庫做消息的持久化,支持多個Slave,所有broker持久化數據源配置成同一個數據源,當一個broker獲取的數據庫鎖之後,其他的broker都成爲slave並且等待獲取鎖,當master掛了之後,其中的一個slave將會立刻獲得數據庫鎖成爲master,重啓之前掛掉的master之後,這個master也就成了slave,不需要停止slave來恢復。由於採用的是數據庫做爲持久化,它的性能是有限的。
3、文件共享方式
這種方式的主備具有和數據庫共享方式的負載一樣的特性,不同的是broker的持久化採用的是文件(我這裏用KahaDB),slave等待獲取的鎖是文件鎖,它具有更高的性能,但是需要文件共享系統的支持。
Window下共享KahaDB持久化的目錄,配置如下:

Linux下需要開啓NFS服務,具體操作如下:
創建共享目錄(192.168.0.1):
1、 修改etc/exports,添加需要共享的目錄:/opt/mq/data *(rw,no_root_squash)
2、 啓動NFS服務 service nfs start/restart
3、 查看共享 showmount –e
4、 NFS服務自啓動 chkconfig –level 35 nfs on

掛載共享目錄(192.168.0.2):
1、 掛載:mount –t nfs 192.168.0.1:/opt/mq/data /opt/mq/data
2、 啓動自動掛載:在etc/fstab文件添加10.175.40.244:/opt/mq/data /opt/mq/data nfs defaults 0 0
然後指定KahaDB的持久化目錄爲/opt/mq/data即可。

AIX系統的文件共享和Linux類似,也是啓動NFS服務。
注意:如果Master服務器宕機了,Slave是不會獲得文件鎖而啓動,直到Master服務器重啓。
Window下Master上有Slave連接時如圖:

客戶端連接的brokerURL爲failover:(tcp://localhost:61616,tcp://localhost:61617)。用第三部分的代碼測試,先向Master Broker發送一個消息,然後關閉master,運行獲取消息的方法,即可獲取之前發送的消息。


ActiveMQ性能優化

1、目標策略

在節點destinationPolicy配置策略,可以對單個或者所有的主題和隊列進行設置,使用流量監控,當消息達到memoryLimit的時候,ActiveMQ會減慢消息的產生甚至阻塞,destinationPolicy的配置如下:

producerFlowControl表示是否監控流量,默認爲true,如果設置爲false,消息就會存在磁盤中以防止內存溢出;memoryLimit表示在producerFlowControl=”true”的情況下,消息存儲在內存中最大量,當消息達到這個值時,ActiveMQ會減慢消息的產生甚至阻塞。policyEntry的屬性參考:http://activemq.apache.org/per-destination-policies.html

當producer發送的持久化消息到達broker之後,broker首先會把它保存在持久存儲中。接下來,如果發現當前有活躍的consumer,如果這個consumer消費消息的速度能跟上producer生產消息的速度,那麼ActiveMQ會直接把消息傳遞給broker內部跟這個consumer關聯的dispatch queue;如果當前沒有活躍的consumer或者consumer消費消息的速度跟不上producer生產消息的速度,那麼ActiveMQ會使用Pending Message Cursors保存對消息的引用。在需要的時候,Pending Message Cursors把消息引用傳遞給broker內部跟這個consumer關聯的dispatch queue。以下是兩種Pending Message Cursors:

VM Cursor:在內存中保存消息的引用。

File Cursor:首先在內存中保存消息的引用,如果內存使用量達到上限,那麼會把消息引用保存到臨時文件中。

在缺省情況下,ActiveMQ 會根據使用的Message Store來決定使用何種類型的Message Cursors,但是你可以根據destination來配置Message Cursors。

對於topic,可以使用的pendingSubscriberPolicy 有vmCursor和fileCursor。可以使用的PendingDurableSubscriberMessageStoragePolicy有

vmDurableCursor 和 fileDurableSubscriberCursor;對於queue,可以使用的pendingQueuePolicy有vmQueueCursor 和 fileQueueCursor。

Message Cursors的使用參考:http://activemq.apache.org/message-cursors.html

2、存儲設置

設置消息在內存、磁盤中存儲的大小,配置如下:

memoryUsage表示ActiveMQ使用的內存,這個值要大於等於destinationPolicy中設置的所有隊列的內存之和。

storeUsage表示持久化存儲文件的大小。

tempUsage表示非持久化消息存儲的臨時內存大小。


使用過程中出現的問題

報錯日誌:Usage Manager Store is Full, 100% of 1073741824. Stopping producer (ID:db01-48754-1336034955132-0:5:1:1) to prevent flooding queue://queue.land.group. See http://activemq.apache.org/producer-flow-control.html for more info (blocking for: 1s) | org.apache.activemq.broker.region.Queue | ActiveMQ Transport: tcp:///172.24.99.41:44716

這是由於我們在配置文件中設置了storeUsage ,當存儲的消息文件(log文件)超過了這值就會報這個異常,在官方網站看到說消息文件不刪除是5.3版本的一個bug,在5.5版本的時候已經被解決了,但是我們使用的是5.5.1版本啊,然後在看存儲下來的消息文件,文件名不是連續的,那麼說明其中還是有被刪除的,後來在評論中看到Jeff Genender 說的這個可能是ActiveMQ的線程調度問題,只要不使用線程調度就可以了,在broker中設置屬性schedulerSupport=”false” ,這樣消息文件就會自動在cleanup階段刪除了。

官方網址:https://issues.apache.org/jira/browse/AMQ-2736?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章