登录ActiveMQ管理端可以看到ActiveMq有一个默认的死信队:ActiveMQ.DLQ ,若未做设置则处理失败的消息会自动进入此队列。本文将展示如何在Spring中引入私信重发机制。
1.ActiveMQ 部署时修改activemq.xml
在policyEntries节点中增加如下策略配置。
<policyEntry queue=">">
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" processNonPersistent="true"/>
</deadLetterStrategy>
</policyEntry>
2.服务端spring-mq配置文件做如下配置
<?xml version="1.0" encoding="UTF-8"?>
<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-4.0.xsd"
default-lazy-init="true">
<!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<!--<amq:connectionFactory id="amqConnectionFactory"
brokerURL="${brokerUrl}" userName="${mq.userName}" password="${mq.password}" redeliveryPolicy="activeMQPolicy" />-->
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${brokerUrl}"></property>
<property name="userName" value="${mq.userName}"></property>
<property name="password" value="${mq.password}"></property>
<property name="redeliveryPolicy" ref="activeMQPolicy" /> <!-- 引用重发机制 -->
</bean>
<!-- 加入死信机制 -->
<bean id="activeMQPolicy" class="org.apache.activemq.RedeliveryPolicy">
<!--是否在每次尝试重新发送失败后,增长这个等待时间 -->
<property name="useExponentialBackOff" value="true"></property>
<!--重发次数,默认为6次 这里设置为1次 -->
<property name="maximumRedeliveries" value="1"></property>
<!--重发时间间隔,默认为1秒 -->
<property name="initialRedeliveryDelay" value="1000"></property>
<!--第一次失败后重新发送之前等待500毫秒,第二次失败再等待500 * 2毫秒,这里的2就是value -->
<property name="backOffMultiplier" value="2"></property>
<!--最大传送延迟,只在useExponentialBackOff为true时有效(V5.5),假设首次重连间隔为10ms,倍数为2,那么第
二次重连时间间隔为 20ms,第三次重连时间间隔为40ms,当重连时间间隔大的最大重连时间间隔时,以后每次重连时间间隔都为最大重连时间间隔。 -->
<property name="maximumRedeliveryDelay" value="1000"></property>
<!---->
<property name="destination" ref="allDestination"></property>
</bean>
<!-- Spring Caching连接工厂 -->
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<!-- 同上,同理 -->
<!-- <constructor-arg ref="amqConnectionFactory" /> -->
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="100"/>
</bean>
<!-- 定义Queue监听器 -->
<bean id="allDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="C2S.Q.TEST" />
</bean>
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListener" ref="dataReceiver" /><!--dataReceiver为MQ处理类,根据实际情况配置-->
<property name="destination" ref="allDestination" />
<property name="sessionTransacted" value="true"/>
</bean>
3.服务端消息处理代码抛出 RuntimeExpection异常
catch (JMSException e) {
e.printStackTrace();
throw new RuntimeException("消息处理异常");
}