当前位置: 首页 > 知识库问答 >
问题:

使用特定于路由的DLQ配置Java/CAMEL/AMQ

丌官晨
2023-03-14

这里是Java 8/Camel 2.19.x/AMQ 5.15.x。

我有一个Java应用程序,它使用Camel来使用AMQ队列中的消息,处理这些消息,并处理这些消息。有时路由的输出是将处理结果备份到另一个队列中,以供进一步的下游处理,但并不总是/必须。典型的Java/CAMEL/AMQ设置。

我的每条路由(我使用的是Camel XML DSL)都有一个配置的 处理程序,通常如下所示:

<onException useOriginalMessage="true">
  <exception>java.lang.Exception</exception>

  <redeliveryPolicy logStackTrace="true"/>

  <handled>
    <constant>true</constant>
  </handled>

  <log message="${exception.stacktrace}" loggingLevel="ERROR"/>

  <rollback markRollbackOnly="true"/>

</onException>

非常简单:记录异常并回滚。

也就是说,如果我的应用程序有30条路由,每条路由都从30个不同的AMQ队列中消耗,那么我将有30个不同的“DLQ”,它们各自的 处理程序将向其中发送失败消息。

理想情况下,我希望该配置位于AMQ端(也可能位于activem.xml或类似内容的内部),这样,如果需要更改DLQ目的地,我就不需要进行代码更改或重新部署。但是如果只能从Camel route/config内部执行,也可以。

我想我可以修改每条路由,使其包含原始消息的自定义目的地DLQ:

<onException useOriginalMessage="true">
  <exception>java.lang.Exception</exception>

  <redeliveryPolicy logStackTrace="true"/>

  <handled>
    <constant>true</constant>
  </handled>

  <log message="${exception.stacktrace}" loggingLevel="ERROR"/>

  <rollback markRollbackOnly="true"/>

  <to uri="activemq:fizzbuzz.dlq"/>

</onException>

但我希望有比这更优雅的东西...

有什么办法让我这么做吗?

共有1个答案

计胤
2023-03-14

也许这样对你会更好:

             DeadLetterChannelBuilder errorHandlerBuilder = deadLetterChannel("jms:dummy");
    errorHandlerBuilder.onPrepareFailure(exchange -> {
        exchange.getIn().setHeader("CamelJmsDestinationName",exchange.getIn().getHeader("JMSDestination",String.class).concat(".DLQ"));
    });

    from("jms:input1")
            .to("seda:process");

    from("jms:input2")
            .to("seda:process");

    from("jms:input3")
            .to("seda:process");

    from("seda:process").errorHandler(errorHandlerBuilder)
            .process(exchange -> {
                throw new RuntimeException();
            });

您可以在运行时计算DLQ队列名称。DeadLetterChannelBuilder也可以像onException一样进行配置。

 类似资料:
  • Apache camel留档描述了如何使用@Component和SpringRouteBuilder注册路由生成器,然后跳转到xml代码 我如何用java配置做同样的事情?我有 和 组件是由Spring拾取并创建的,这部分很好。我可以通过注册路由。唯一缺少的是如何告诉骆驼上下文拾取路由,如果它被管理为Spring bean。

  • 我正在尝试创建一个webservice,当调用它时,它会查看本地目录,从那里提取文件并上传到ftp服务器。 我可以创建一个简单的路由,从本地目录中选择文件并上传到ftp服务器,下面是代码: 但是,我想在通过restlet webservice调用特定路由时调用此文件传输,我尝试了以下代码,但没有成功: restlet从以下路径调用上述路径: 以下是我的serviceRouteProcessor的代

  • 每个路由可以有不同的属性; 一些常见的属性是: path - 应用程序在特定路由上时在浏览器中显示的URL component - 当应用程序在特定路由上时要呈现的组件 pathMatch - 默认为’prefix’的可选属性。 确定是匹配完整的网址还是仅匹配开头。 当定义一个具有空路径字符串的路径设置pathMatch为’full’时,否则它将匹配所有路径。 children - 表示此路由的子

  • 我使用代理activemq 5.5.1和Spring JMS进行消息传递。我有如下要求 A) 我只想在相应的异常发生时将消息推入DLQ。目前,根据我的理解,在指定重试参数后,从MessageListeners抛出的任何异常都会移动到DLQ。ActiveMQ是否提供此功能以及如何提供? B) 我必须根据类级别控制重试机制,这意味着自定义异常不重试。例如,如果抛出了MyException类的实例,那么

  • 我可以检查对象中的值并基于此进行路由吗(就像写到不同的文件一样?)。我可以在pojo中添加注释以避免final json中的字段 我想到了将object转换为json,然后发送到Queue。然后我可以使用jsonpath进行条件路由。但是,我怎样才能从final JSON中省略一个字段呢?

  • 我试图在Wildfly Swarm中设置一个Camel Rest服务,但我不确定类是如何实例化的,甚至不知道是如何实例化的。我下载了Wildfly Swarm示例,并查看了Camel CXF-JAXRS项目,这是有意义的,但它使用XML定义路由。我想使用Java DSL。我的类如下所示: 我已经尝试过使用和不使用文件。Swarm启动,但我无法浏览到rest服务endpoint。 如何调用?我应该有