Christian, great question...I see various forms of this asked many times.
I've considered all the options you mentioned, but for high-volume/critical
messaging scenarios, I struggle with the idea of leaving messages up to the
AMQ config/inflight repositories for lack of control/visibility/testability,
etc...
For these reasons, I generally end up doing something like this...catch all
errors and send to a separate queue to be periodically retried independent
of the main route. I like this mainly because its simple/clean, puts all
errors in a queue for triage (viewing, clearing, altering, manually
retrying, etc), and has a separate (retry) route that can be
stopped/started, etc.
basically, something like this...
//main route to process message from a queue (needs to be fast)
from(activemq:queue:foo)
.to("cxf:bean:orderService")
.to("activemq:queue:bar");
//handle any errors by simply moving them to an error queue (for retry
later)
onException(Exception.class)
.handled(true).to("activemq:queue:fooErrorQ");
//retry the error queue every 10 minutes
from("timer://retryTimer?fixedRate=true&period=60000")
.pollEnrich("activemq:queue:fooErrorQ")
.to("cxf:bean:orderService")
.to("activemq:queue:bar");
That being said, this seems a bit archaic/simplistic given all the other
options. Either way, I'm interested in other takes on this as well...
Christian Mueller wrote:
>
> Hello!
>
> To illustrate the missing feature, assume we have the following route:
> from(activemq:queue:foo)
> .to("cxf:bean:orderService")
> .to("activemq:queue:bar");
>
> Our orderService is out of order every day for 30 min - 60 min. In this
> time, we cannot process messages from the foo queue. We have to delay the
> processing until the orderService returns to operate normal. We have
> multiple possibilities at present to handle the requirement, but all have
> some drawbacks, IMO.
>
> 1) Make the route transacted and let the ActiveMQ Broker do the
> (redelivery)
> work.
> from(activemq:queue:foo)
> .transacted("REQUIRED")
> .to("cxf:bean:orderService")
> .to("activemq:queue:bar");
>
> Drawbacks:
> - We are not the owner of this configuration cannot ensure the ActiveMQ
> broker/JMSConnectionFactory is configured properly for the redelivery.
> - We cannot use different redelivery policies for different routes.
>
>
> 2) Use the Camel dead letter error handler to catch the errors and do the
> redelivery.
> errorHandler(
> deadLetterChannel(activemq:queue:foo.DLQ)
> .maximumRedeliveries(8)
> .deliveryDelay(60000)
> .useExponentialBackOff()
> .backOffMultiplier(2));
>
> from(activemq:queue:foo)
> .to("cxf:bean:orderService")
> .to("activemq:queue:bar");
>
> Drawbacks:
> - When we are in the seventh redelivery, we will wait over one hour for
> the
> next redelivery. If we have to shout down our container (which is
> ServiceMix), it will take over one hour or we have to force the shutdown
> and
> we loose the message.
>
>
> To solve the missing feature, we have at least two options:
>
>
> a) Provide a "special" error handler which uses the "delay and schedule
> message delivery" feature from ActiveMQ [3]. This error handler
> should/could
> looks like the RedeliveryErrorHandler:
> errorHandler(
> activeMqDeadLetterChannel(activemq:queue:foo.DLQ)
> .maximumRedeliveries(8)
> .deliveryDelay(60000)
> .useExponentialBackOff()
> .backOffMultiplier(2));
>
> from(activemq:queue:foo)
> .to("cxf:bean:orderService")
> .to("activemq:queue:bar");
>
> If an error occurs, this error handler should evaluate the (JMS) headers
> whether or not the message should redelivered, which delay should be used,
> update the (JMS) headers with the new values and enqueue the message again
> into the queue the message was read from. May be this route must/should
> also
> be transacted to make sure we do not loose messages.
>
>
> b) Add the options described in [1] and [2] to the activemq component to
> allow the user to specify the redelivery behavior per endpoint definition:
> from(activemq:queue:foo?maximumRedeliveries=10&deliveryDelay=60000&useExponentialBackOff=true&backOffMultiplier=2)
> .transacted("REQUIRED")
> .to("cxf:bean:orderService")
> .to("activemq:queue:bar");
>
> This options should be used to configure the JMSConnection.
> I know it's also possible to configure this in the
> ActiveMQConnectionFactory, but:
> - We are not the "owner" of this configuration. We use an OSGI lookup to
> get
> the reference to the exported ActiveMQConnectionFactory.
> - It's a global configuration and we may need the possibility to override
> some options (deliveryDelay) for other routes.
>
>
> Do I miss something? What are your thoughts?
>
>
> [1] http://activemq.apache.org/redelivery-policy.html
> [2] http://activemq.apache.org/message-redelivery-and-dlq-handling.html
> [3] http://activemq.apache.org/delay-and-schedule-message-delivery.html
>
> Looking forward for many opinions :-),
> Christian
>
-----
Ben O'Day
IT Consultant -http://benoday.blogspot.com
--
View this message in context:
http://camel.465427.n5.nabble.com/Missing-feature-to-handle-errors-in-a-route-which-reads-from-an-activemq-destination-tp4416986p4417941.html
Sent from the Camel Development mailing list archive at Nabble.com.