当错误被处理时,Apache Camel未从SQS删除消息

后端开发 2026-07-09

我有这些路由定义:

class ContentChangedIngestRoute(
) : RouteBuilder() {

    override fun configure() {
        from("aws2-sqs://myQueue?deleteAfterRead=true")
            .routeId("content-changed-ingest")
            .to("direct:content-changed")
    }
}

class ContentChangedRoute(
    private val contentChangePayloadJacksonDataFormat: JacksonDataFormat
) : RouteBuilder() {

    override fun configure() {

        from("direct:content-changed")
            .routeId("content-changed-parse")
            .routeConfigurationId("parseErrorHandling")
            .unmarshal(contentChangePayloadJacksonDataFormat)
            .to("direct:derive-action")
    }
}

class ParseErrorHandlingRouteConfiguration : RouteConfigurationBuilder() {

    override fun configuration() {
        routeConfiguration("parseErrorHandling")

            .onException(
                InvalidPayloadException::class.java,
                JsonParseException::class.java,
                JsonMappingException::class.java,
                ExpressionEvaluationException::class.java,
                IllegalStateException::class.java
            )
                .useOriginalMessage()
                .handled(true)
                .maximumRedeliveries(0)
                .log(LoggingLevel.ERROR, "Parse/mapping error [route=\${routeId}, exchange=\${exchangeId}]: \${exception.message}")
                .to("seda:dlq.parse")
            .end()
    }
}

现在,当JSON中有一个必填字段未填写时,错误处理能够正确工作,错误也被记录。但我本来希望消息会因为.handled(true) 而从队列中被删除。不过同一条消息却一遍又一遍地被处理。

解决方案

我在使用Camel 4.20和 Spring Boot 4.0.6。

如果我在AWS SQS消费者路由内定义错误处理器,消息将只被处理一次,重定向到死信队列处理器,然后从队列中删除。

from(aws2Sqs("myQueue")
  .autoCreateQueue(true)
  .useDefaultCredentialsProvider(true)
  .deleteAfterRead(true))
.errorHandler(deadLetterChannel("seda:dlq")
  .maximumRedeliveries(0)
  .log(LOG)
  .logHandled(true)
  .logExhausted(true))
.log("Consumed SQS: ${body}")
.throwException(new RuntimeException("Network error"));

from(timer("producer").repeatCount(1))
 .setBody(constant("Camel Rocks!"))
 .to(aws2Sqs("myQueue").useDefaultCredentialsProvider(true))
 .log(LoggingLevel.INFO, LOG, "Produced SQS: ${body}");

from(seda("dlq"))
  .log("Message handled in dlq endpoint");

日志中我看到这个

在此输入图片描述

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章