ActiveMQ的另一個問題就是隻要是軟體就有可能掛掉,掛掉不可怕,怕的是掛掉之後把資訊給丟了,所以本節分析一下幾種持久化方式:
一、持久化為檔案
ActiveMQ預設就支援這種方式,只要在發訊息時設定訊息為持久化就可以了。
開啟安裝目錄下的配置檔案:
D:\ActiveMQ\apache-activemq\conf\activemq.xml在越80行會發現預設的配置項:
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
注意這裡使用的是kahaDB,是一個基於檔案支援事務的訊息儲存器,是一個可靠,高效能,可擴充套件的訊息儲存器。
他的設計初衷就是使用簡單並儘可能的快。KahaDB的索引使用一個transaction log,並且所有的destination只使用一個index,有人測試表明:如果用於生產環境,支援1萬個active connection,每個connection有一個獨立的queue。該表現已經足矣應付大部分的需求。
然後再傳送訊息的時候改變第二個引數為:
MsgDeliveryMode.Persistent
Message儲存方式有2種
PERSISTENT:儲存到磁碟,consumer消費之後,message被刪除。
NON_PERSISTENT:儲存到記憶體,消費之後message被清除。
注意:堆積的訊息太多可能導致記憶體溢位。
然後開啟生產者端傳送一個訊息:
不啟動消費者端,同時在管理介面檢視:
發現有一個訊息正在等待,這時如果沒有持久化,ActiveMQ當機後重啟這個訊息就是丟失,而我們現在修改為檔案持久化,重啟ActiveMQ後消費者仍然能夠收到這個訊息。
二、持久化為資料庫
我們從支援Mysql為例,先從http://dev.mysql.com/downloads/connector/j/下載mysql-connector-java-5.1.34-bin.jar包放到:
D:\ActiveMQ\apache-activemq\lib目錄下。
開啟並修改配置檔案:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <!-- Allows us to use system properties as variables in this configuration file --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>file:${activemq.conf}/credentials.properties</value> </property> </bean> <!-- Allows accessing the server log --> <bean id="logQuery" class="org.fusesource.insight.log.log4j.Log4jLogQuery" lazy-init="false" scope="singleton" init-method="start" destroy-method="stop"> </bean> <!-- The <broker> element is used to configure the ActiveMQ broker. --> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <destinationPolicy> <policyMap> <policyEntries> <policyEntry topic=">" > <!-- The constantPendingMessageLimitStrategy is used to prevent slow topic consumers to block producers and affect other consumers by limiting the number of messages that are retained For more information, see: http://activemq.apache.org/slow-consumer-handling.html --> <pendingMessageLimitStrategy> <constantPendingMessageLimitStrategy limit="1000"/> </pendingMessageLimitStrategy> </policyEntry> </policyEntries> </policyMap> </destinationPolicy> <!-- The managementContext is used to configure how ActiveMQ is exposed in JMX. By default, ActiveMQ uses the MBean server that is started by the JVM. For more information, see: http://activemq.apache.org/jmx.html --> <managementContext> <managementContext createConnector="false"/> </managementContext> <!-- Configure message persistence for the broker. The default persistence mechanism is the KahaDB store (identified by the kahaDB tag). For more information, see: http://activemq.apache.org/persistence.html <kahaDB directory="${activemq.data}/kahadb"/> --> <persistenceAdapter> <jdbcPersistenceAdapter dataDirectory="${activemq.base}/data" dataSource="#derby-ds"/> </persistenceAdapter> <!-- The systemUsage controls the maximum amount of space the broker will use before disabling caching and/or slowing down producers. For more information, see: http://activemq.apache.org/producer-flow-control.html --> <systemUsage> <systemUsage> <memoryUsage> <memoryUsage percentOfJvmHeap="70" /> </memoryUsage> <storeUsage> <storeUsage limit="100 gb"/> </storeUsage> <tempUsage> <tempUsage limit="50 gb"/> </tempUsage> </systemUsage> </systemUsage> <!-- The transport connectors expose ActiveMQ over a given protocol to clients and other brokers. For more information, see: http://activemq.apache.org/configuring-transports.html --> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> <!-- destroy the spring context on shutdown to stop jetty --> <shutdownHooks> <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" /> </shutdownHooks> </broker> <bean id="derby-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true"/> <property name="username" value="root"/> <property name="password" value=""/> <property name="maxActive" value="200"/> <property name="poolPreparedStatements" value="true"/> </bean> <!-- Enable web consoles, REST and Ajax APIs and demos The web consoles requires by default login, you can disable this in the jetty.xml file Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details --> <import resource="jetty.xml"/> </beans> <!-- END SNIPPET: example -->
重啟ActiveMQ開啟phpmyadmin發現多了3張表:
然後啟動生產者(不啟動消費者)
在Mysql中可以找到這條訊息:
關掉ActiveMQ並重啟,模擬當機。
然後啟動消費者:
然後發現Mysql中已經沒有這條訊息了。