ActiveMQ 填坑记

前言

MQ是如今大型系统架构中必不可少的一个重要中间件,以前有偏文章《MQ(消息队列)常见的应用场景解析》介绍过MQ的应用场景,如今流行的几个MQ是rabbitmq,rocketma,kafka,这几个MQ比较最容易找到相关的文章,而也有些系统使用的是activemq,因activemq是相对比较传统的MQ,在使用过程当中仍是会遇到不少坑,这里简单列举几个你们可能会遇到的问题,把本身使用acitvemq的经验和你们分享一下。java

Mysql 持久化

如今你们使用MQ,基本都是会把数据进行持久化,MQ默认存储持久化数据使用kahaDB,可是鉴于你们对mysql比较熟悉,不少人会选择mysql进行数据的持久化,由于mysql查看数据仍是比较方便的。若是须要把持久化方式改成mysql,则须要修改以下配置:mysql

<persistenceAdapter>
            <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" createTablesOnStartup="false" useDatabaseLock="false"/>
            <!-- 下面是默认的kahaDB方式,注释掉 -->
        <!-- <kahaDB directory="${activemq.data}/kahadb"/> -->
        </persistenceAdapter>

这里的配置有几个地方你们须要关注下:sql

配置 说明
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应该是同样的。不然,不知道链接哪一个实例。apache

数据库链接池问题

启动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其实不是一个很好的选择,反其道而行之,虽然这样用的团队很多,可是强烈推荐不要这么作。仍是用默认的存储方式,确保性能为主。ide

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的消费状况,最好能设置过时时间,按期清理消息队列的数据,避免数据的积累,形成性能的降低。


微信号:itmifen

相关文章
相关标签/搜索