我正在努力使信息能够在Camel中保留重新传递信息:
from("activemq:incoming-queue")
.errorHandler(
deadLetterChannel("activemq:queue.dead-letter")
.maximumRedeliveries(100)
.redeliveryDelay(TimeUnit.SECONDS.toMillis(10))
)
.to("http4://example.com")
如果发生故障,则会安排重试,如果我们关闭Camel,它会将消息放回ActiveMQ队列,这是好的。
问题是如果你用“kill -9”杀死它,那么消息将永远丢失,因为Camel在重试期间将它们保存在内存中。
问题是如何保证即使在系统突然中断的情况下,重试也不会丢失消息?
更新
我们使用交易实施了有保证的重新发送:
@Bean
public JmsTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) {
JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
jmsTransactionManager.setConnectionFactory(connectionFactory);
return jmsTransactionManager;
}
/**
* Disables ActiveMQ redelivery since it clashes with camel redelivery system
*/
@Bean
public RedeliveryPolicy redeliveryPolicy(ActiveMQConnectionFactory connectionFactory) {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(0);
connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
return redeliveryPolicy;
}
然后路由如下所示(注意transacted = true参数,由于某些原因.transacted()方法的行为不同):
from("activemq:incoming-queue?transacted=true")
.errorHandler(
deadLetterChannel("activemq:queue.dead-letter")
.maximumRedeliveries(100)
.redeliveryDelay(TimeUnit.SECONDS.toMillis(10))
)
.to("http4://example.com")
使用这种方法有什么缺点吗?
答案 0 :(得分:3)
让克劳斯的回答更加具体:
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.url}"/>
<property name="userName" value="${activemq.userName}"/>
<property name="password" value="${activemq.password}"/>
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="100"/>
<property name="initialRedeliveryDelay" value="10000"/>
<property name="redeliveryDelay" value="10000"/>
</bean>
</property>
</bean>
使用ActiveMQ重试100次,第一次重试等待10秒,然后每次重试等待10秒。
然后你可以省略Camel中的错误处理(从而将它留给ActiveMQ),但我会添加事务:
from("activemq:incoming-queue")
.transacted("PROPAGATION_REQUIRED_JMS")
.to("http4://example.com")
重试100次后,消息将以队列“ActiveMQ.DLQ”结束,除非你改变它。
答案 1 :(得分:2)
最好在ActiveMQ代理端配置这种持久重传,你可以这样做,因为它具有这样的功能。