关于ActiveMQ中Topic持久化配置问题

说明:记录一下在ActiveMQ中踩过的坑。
关键字:jms:listener-container,topic订阅持久化。

  1. Demo的目录结构(说明中有各个文件的作用)
    这里写图片描述
    不懂ActiveMQ的可以,在网上搜搜,有很多很好的博客,在这里我只简单的介绍怎么用,标注一些坑。哪里不足,欢迎提出。

    前提:activeMQ(解压之后的文件夹)–conf –activemq.xml
    这里写图片描述
    这里写图片描述

  2. application-mqp.xml(生产者.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context    
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       ">
       <!-- 扫描包 -->
    <context:component-scan base-package="com.roger.activemq" />
       <!-- activeMQ连接工厂 -->
    <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616"></property>
        <property name="userName" value="admin"></property>
        <property name="password" value="admin"></property>
    </bean>
        <!-- Spring caching连接工厂 -->
    <bean id="mqConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
        <property name="sessionCacheSize" value="100"></property>
    </bean>
        <!-- Spring JmsTemplate 的消息生产者 -->
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate" >
        <constructor-arg ref="mqConnectionFactory"/>
        <!-- 队列模式 -->
        <property name="pubSubDomain" value="false"/>
        <!-- 持久化 -->
        <property name="deliveryMode" value="2"/>
        <!-- 存活时间 -->
        <!-- <property name="timeToLive" value="6000000"/> -->
        <!-- 开启服务质量的开关   开启之后上面的配置才会生效 -->
        <property name="explicitQosEnabled" value="true"/>
    </bean>
    <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate" >
        <constructor-arg ref="mqConnectionFactory"/>
        <!-- 广播模式 -->
        <property name="pubSubDomain" value="true"/>
        <!-- 持久化 -->
        <property name="deliveryMode" value="2"/>
        <!-- 存活时间 -->
        <!-- <property name="timeToLive" value="6000000"/> -->
        <!-- 开启服务质量的开关   开启之后上面的配置才会生效 -->
        <property name="explicitQosEnabled" value="true"/>
    </bean>
</beans>

注:JmsTemplate中的配置不止这些,这里只关注topic持久化。

这段配置是开启持久化,topic模式发送的消息,会保存在broker中,是topic持久化的前提
<property name="deliveryMode" value="2"/>
  1. application-mqc.xml(消费者.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jms="http://www.springframework.org/schema/jms"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/jms 
       http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
       ">
    <!-- 扫描包 -->
    <context:component-scan base-package="com.mq.consumer" />
    <!-- activeMQ连接工厂 -->
    <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616"></property>
        <property name="userName" value="admin"></property>
        <property name="password" value="admin"></property>
    </bean>
        <!-- Spring caching连接工厂 -->
    <bean id="mqConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
        <property name="clientId" value="client_119" />
        <property name="sessionCacheSize" value="100"></property>
    </bean>

    <!-- 事务管理器 -->
    <bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory" ref="amqConnectionFactory"/>
    </bean>

    <!-- 队列监听 -->
    <jms:listener-container destination-type="queue" container-type="default" 
        connection-factory="mqConnectionFactory" acknowledge="transacted" transaction-manager="jmsTransactionManager">
        <!-- 配置监听目标 和监听的对象 -->
        <jms:listener destination="spring_queue" ref="consumerQueue1"/>
        <jms:listener destination="spring_queue" ref="consumerQueue2"/>
    </jms:listener-container>
    <!-- 广播监听 -->
    <jms:listener-container destination-type="durableTopic" container-type="default"  
        connection-factory="mqConnectionFactory"  acknowledge="transacted" transaction-manager="jmsTransactionManager">
        <!-- 配置监听目标 和监听的对象 -->
        <jms:listener destination="spring_topic" ref="consumerTopic1" subscription="test.Consumer"/>
        <jms:listener destination="spring_topic" ref="consumerTopic2" subscription="test.Consumer1"/>
    </jms:listener-container>
</beans>
拆开分析:
<!-- Spring cachingl连接工厂 -->
    <bean id="mqConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
        <property name="clientId" value="client_119" />
        <property name="sessionCacheSize" value="100"></property>
    </bean>

注:可以看到这里给连接工厂配置了一个属性clientId。

<!--  part2  -->
 <!-- 广播监听 -->
    <jms:listener-container destination-type="durableTopic" container-type="default"  
        connection-factory="mqConnectionFactory"  acknowledge="transacted" transaction-manager="jmsTransactionManager">
        <!-- 配置监听目标 和监听的对象 -->
        <jms:listener destination="spring_topic" ref="consumerTopic1" subscription="test.Consumer"/>
        <jms:listener destination="spring_topic" ref="consumerTopic2" subscription="test.Consumer1"/>
    </jms:listener-container>

注:destination-type=”durableTopic”配置成持久化Topic类型

<jms:listener destination="spring_topic" ref="consumerTopic1" subscription="test.Consumer"/>
<jms:listener destination="spring_topic" ref="consumerTopic2" subscription="test.Consumer1"/>

可以看见这里配置了两个监听者,监听的是同一个destination,但是它们的subscription是不同的,关键点就是subscription和连接工厂的ClientID组成了一个名字,这个名字会在broker(个人理解ActiveMQ服务平台) 上面注册(报名订阅)。

通俗一点理解:张三和李四都在食堂吃饭,都需要报名到食堂管理员那,食堂管理员会记录每个人的名字。到中午吃饭时,不管张三或李四来不来吃,都会给他们留一份。

测试步骤:
1.开启ActiveMQ的服务
2.在consumerTest中空跑一次,然后在关闭。目的就是在broker中报名订阅,名字就是subscription+ClientID组成的唯一名字。
3.关闭所有的listener之后,运行providerTest,发布topic消息。(如果是非持久化订阅时,listener是接收不到消息的,持久化topic了之后,就可以接收到了。)
附上Demo:http://download.csdn.net/download/qq_34934864/10147325

没有更多推荐了,返回首页