Java 驼峰路由无限运行以移动JMS消息
我正在尝试使用驼峰路由器以5分钟的周期间隔将消息从活动MQ中的队列1(死信队列)移动到队列2。我使用以下代码来实现此目的:-Java 驼峰路由无限运行以移动JMS消息,java,apache-camel,activemq,camel-jms,Java,Apache Camel,Activemq,Camel Jms,我正在尝试使用驼峰路由器以5分钟的周期间隔将消息从活动MQ中的队列1(死信队列)移动到队列2。我使用以下代码来实现此目的:- public class MessageRouteBuilder extends RouteBuilder { private static final Logger LOG = LoggerFactory.getLogger(MessageRouteBuilder.class); /* * (non-Java
public class MessageRouteBuilder extends RouteBuilder {
private static final Logger LOG =
LoggerFactory.getLogger(MessageRouteBuilder.class);
/*
* (non-Javadoc)
*
* @see org.apache.camel.builder.RouteBuilder#configure()
*/
@Override
public void configure() throws Exception {
LOG.info("Routing of camel is started");
CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
startPolicy.setRouteStartTime("0 0/5 * * * ?");
from(
"jms:queue:DLQ.Consumer.OUTDOCS.VirtualTopic.queue1")
.routeId("DLQMessageMoverID").routePolicy(startPolicy)
.noAutoStartup()
.to("jms:queue:Consumer.OUTDOCS.VirtualTopic.queue1");
LOG.info("Routing of camel is done");
}
}
@Startup
@Singleton
public class ScheduledMessageDLQConsumer {
@Inject
private MessagingUtil msgUtil;
@Inject
private MessageRouteBuilder builder;
private static final Logger LOG =
LoggerFactory.getLogger(ScheduledMessageDLQConsumer.class);
@PostConstruct
public void init() {
LOG.info("camel Scheduling scheduled started");
CamelContext camelContext = new DefaultCamelContext();
ConnectionFactory connectionFactory = msgUtil.getAMQConnectionFactory();
camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
try {
camelContext.addRoutes(builder);
camelContext.start();
LOG.info("Camel scheduling completed");
} catch (Exception e) {
// TODO Auto-generated catch block
LOG.error("Error in registering camel route builder", e);
}
LOG.info(" camel Scheduling scheduled completed");
}
}
这里的问题是:-骆驼路由在5分钟后启用。它将消息从DLQ(DLQ.Consumer.OUTDOCS.VirtualTopic.queue1)移动到queue1(Consumer.OUTDOCS.VirtualTopic.queue1)。但是,如果消息是有毒的,它会再次返回到DLQ,并且再次路由将消息从DLQ移动到正常队列,并且这个过程会无限期地运行
我的要求是,路由应该每5分钟将消息从DLQ移动到队列一次?如果有毒信息出现,应该在5分钟后检查。首先,你的整个想法看起来很糟糕。再加工和再交付应由消费者或经纪人处理,不得有任何晦涩难懂的定期“DLQMessageOver”。如果您控制了OUTDOCS.VirtualTopic.queue1中的应用程序使用,请重新思考错误处理的概念 顺便说一句,消费者连接上的=-1和=300000的简单组合将与您在这个问题中编写的所有代码具有相同的影响 其次,您需要在名为JMSCorrelationID的头上使用相关键。此过程仅对每个关联id执行一次。当使用时,它会在路由重新启动时被清除,所以消息会再次被处理,这符合您的要求 我创建了一个小示例来展示它是如何工作的。在您的情况下,不会模拟JMSCOrrationId头和jms组件而不是计时器
public class IdempotentConsumerRouteBuilder extends RouteBuilder {
private final IdempotentRepository idempotentRepository = new MemoryIdempotentRepository();
private final List<String> mockCorrelationIds = Arrays.asList("id0","id0","id0","id1","id2","id0","id4","id0","id6","id7");
public void configure() {
CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
startPolicy.setRouteStopTime("0 0/5 * * * ?");
startPolicy.setRouteStartTime("0 0/5 * * * ?");
from("timer:jms?period=100")
.routePolicy(startPolicy)
.process(e -> e.getIn().setHeader(
"JMSCorrelationID", //Mock JMSCorrelationID to work with timer as it is jms component
mockCorrelationIds.get(e.getProperty("CamelTimerCounter", Integer.class)%10))
)
.idempotentConsumer(header("JMSCorrelationID"), idempotentRepository)
.log("correlationId is ${header.JMSCorrelationID}")
.to(("log:done?level=OFF"))
.end();
}}
我不明白这是一个多么糟糕的设计。我的用例是定期将消息从DLQ移动到主队列。我认为Camel可以将消息从一个队列移动到另一个队列,而不是编写生产者和消费者代码。你能提供更好的解决方案吗?
[artzScheduler-camel-1_Worker-3] DefaultCamelContext INFO Route: route1 started and consuming from: timer://jms?period=100
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id0
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id1
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id2
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id4
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id6
[mel-1) thread #4 - timer://jms] route1 INFO correlationId is id7
[artzScheduler-camel-1_Worker-6] DefaultShutdownStrategy INFO Starting to graceful shutdown 1 routes (timeout 10000 milliseconds)
[el-1) thread #5 - ShutdownTask] DefaultShutdownStrategy INFO Route: route1 shutdown complete, was consuming from: timer://jms?period=100
[artzScheduler-camel-1_Worker-6] DefaultShutdownStrategy INFO Graceful shutdown of 1 routes completed in 0 seconds
[artzScheduler-camel-1_Worker-6] DefaultCamelContext INFO Route: route1 is stopped, was consuming from: timer://jms?period=100
[artzScheduler-camel-1_Worker-8] ScheduledRoutePolicy WARN Route is not in a started/suspended state and cannot be stopped. The current route state is Stopped
[artzScheduler-camel-1_Worker-7] DefaultCamelContext INFO Route: route1 started and consuming from: timer://jms?period=100
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id0
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id1
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id2
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id4
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id6
[mel-1) thread #6 - timer://jms] route1 INFO correlationId is id7
[rtzScheduler-camel-1_Worker-10] DefaultShutdownStrategy INFO Starting to graceful shutdown 1 routes (timeout 10000 milliseconds)