Mysql 持久化 现在大家使用MQ,基本都是会把数据进行持久化,MQ默认存储持久化数据使用kahaDB,但是鉴于大家对mysql比较熟悉,很多人会选择mysql进行数据的持久化,因为mysql查看数据还是比较方便的。如果需要把持久化方式改为mysql,则需要修改如下配置:

<persistenceAdapter> <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" createTablesOnStartup="false" useDatabaseLock="false"/> <!-- 下面是默认的kahaDB方式,注释掉 --> <!-- <kahaDB directory="${activemq.data}/kahadb"/> --> </persistenceAdapter> 这里的配置有几个地方大家需要关注下:

配置 说明 dataDirectory 需要配置和broker 的dataDirectory 一致 dataSource 数据源的选择,关联数据库的具体配置,下文会具体说明 useDatabaseLock 是否使用数据库锁,主要是在程序启动的时候会同步查询数据,导致数据库锁 还需要配置数据库的连接、账号、密码等:

<!-- MySql DataSource Setup --> <bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://0.0.0.0:3306/activemq?relaxAutoCommit=true"/> <property name="username" value="root"/> <property name="password" value="******"/> <property name="poolPreparedStatements" value="true"/> </bean> 其中,id 名和上文提到的datasource应该是一样的。否则,不知道连接哪个实例。

数据库连接池问题 启动activemq如果提示数据库的连接池有问题,这可能是少了lib,增加

mysql-connector-java-5.1.30.jar commons-dbcp2-2.1.1.jar commons-pool2-2.4.2.jar 三个包,放到lib目录即可

管理界面无法打开 如果正常启动了,但是管理界面无法启动,那么需要修改下管理界面的数据库连接。

使用MQ主要原因之一是MQ性能比传统关系数据库性能要好,但是把MQ数据存储的mysql其实不是一个很好的选择,反其道而行之,虽然这样用的团队不少,但是强烈推荐不要这么做。还是用默认的存储方式,确保性能为主。

activeMQ过期配置 前文说过,activemq性能本来就不是最优的,特别是使用了mysql作为数据库存储工具后,性能更加不靠谱,所以性能优化,是个重要的工作,定期清理MQ的过期信息,就显的非常重要了。

定期清理无效的队列 配置如下:

<destinationPolicy> <policyMap> <policyEntries>

            <policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="10000">
            <deadLetterStrategy>
                <sharedDeadLetterStrategy processExpired="true" expiration="30000"/>
            </deadLetterStrategy>
             </policyEntry>



            <policyEntry topic=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="10000" >
               
              <pendingMessageLimitStrategy>
                <constantPendingMessageLimitStrategy limit="1000"/>
              </pendingMessageLimitStrategy>
            </policyEntry>

          </policyEntries>
          
        </policyMap>
    </destinationPolicy>

定期自动清理无效的Topic和Queue,这个配置,只会清除设置的时间内,没有被订阅,同时队列没有遗留数据的队列。

同时,对于boker节点,需要设置schedulePeriodForDestinationPurge 参数,表示多长之间执行一次检测。

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost01" dataDirectory="${activemq.data}" useJmx="true" schedulePeriodForDestinationPurge="5000"> 设置消息的全局过期时间 开发的时候,大家应该都知道可以设置消息的过期时间,是否有统一设置消息的过期时间呢?

在broker节点下增加如下的配置:

<plugins> <!-- 86400000 为一天,设置为10天过期 --> <timeStampingBrokerPlugin ttlCeiling="10000" zeroExpirationOverride="10000" /> </plugins> 为了便于测试,我设置的是10s,当然,生产环境根据自己的是实际设置的会比较长。过期的时间会进入死信,死信也会沿用此时间,到期后,系统就会自动删除信息了。

经过我个人的实践经验,MQ积累的数据达千万级别后,性能下降的比较厉害,定期清理MQ的消息,是优化性能非常重要的一个操作。

总结 现如今,MQ的选择很多,建议还是优先选择rabbitmq、rocketmq或者是kafka,如果已经选择activemq,需要持续关注MQ的消费情况,最好能设置过期时间,定期清理消息队列的数据,避免数据的积累,造成性能的下降。