Camel中JMS队列满异常重试其余异常转DLQ实现报错问题
解决方案
错误根因
你之前的实现触发报错的核心原因是:在onException(JMSException.class)的处理链路中抛出新的自定义异常时,Camel会判定该操作为异常处理流程本身发生了二次异常,因此直接触发FatalFallbackErrorHandler终止正常流转,不会匹配你定义的第二个onException(QueueFailedException.class)规则。
正确实现方式
不需要拆分多段异常处理,直接利用Camel onException 提供的onWhen断言能力,对同类型异常做分支匹配即可,优先级更高的规则前置定义。
Java DSL 示例
// 规则1:仅匹配队列满场景的JMS异常,配置重试逻辑 onException(JMSException.class) .onWhen(exchange -> { JMSException jmsEx = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, JMSException.class); // 替换为你实际的队列满异常判断逻辑,比如匹配异常消息特征 return jmsEx.getMessage() != null && jmsEx.getMessage().contains("Queue is full"); }) .maximumRedeliveries(5) // 自定义最大重试次数 .redeliveryDelay(2000) // 重试间隔2ms,可按需配置指数退避策略 .useOriginalMessage() // 重试使用原始未修改的消息 .end(); // 规则2:匹配其余所有JMS异常、其他非预期异常,直接投递到DLQ onException(Exception.class) .useOriginalMessage() .to("jms:queue:YOUR_DLQ_QUEUE_NAME") // 替换为实际DLQ队列地址 .handled(true) // 标记异常已处理,终止后续流转 .end();
XML DSL 示例
<!-- 规则1:匹配队列满场景的JMS异常,配置重试 --> <onException> <exception>javax.jms.JMSException</exception> <onWhen> <simple>${exception.message} contains 'Queue is full'</simple> </onWhen> <maximumRedeliveries>5</maximumRedeliveries> <redeliveryDelay>2000</redeliveryDelay> <useOriginalMessage/> </onException> <!-- 规则2:其余异常全部投递DLQ --> <onException> <exception>java.lang.Exception</exception> <useOriginalMessage/> <to uri="jms:queue:YOUR_DLQ_QUEUE_NAME"/> <handled> <constant>true</constant> </handled> </onException>
注意事项
- 请将代码中的异常匹配特征、队列地址、重试参数替换为你实际业务的配置值,不同MQ厂商返回的队列满异常消息格式存在差异,可调整判断逻辑适配实际场景。
- 若队列满异常重试达到最大次数仍失败,会自动匹配后置的通用异常规则,投递到DLQ,符合业务预期。
内容的提问来源于stack exchange,提问作者Claudio Coelho
相关产品推荐
相关产品推荐

