Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

In regards to Regarding startup and shutdown of routes, by default, our the routes are automatically started when your Apache Camel application (ie. the CamelContext instance) starts up. Consequently, these same routes are automatically shut down when your Apache Camel application stops.

...

Also, as another consideration, we typically want to control the order in which routes shut down so that dependencies between different routes and processes are not violated (which would prevent existing tasks from running to completion).

For this reason, Apache Camel provides a set of features to support graceful shutdown of applications. Graceful shutdown gives you full control over the stopping and starting of routes, enabling you to control the shutdown order of routes and enabling current tasks to run to completion.

Setting Route ID

It is a good best practice to assign a unique route ID to each of the routes that we build. This will make logging messages and management features more informative and easier to track. Additionally, the use of route IDs will provide greater control over the stopping and starting of routes.

Using the Java DSL, we can assign the route ID, myProductRouteId, to a route by invoking the routeId() command as follows:

Code Block
from("SourceURI").routeId("myProductRouteId").process(...).to(TargetURI);

In the XML DSL, we can do the same things as follows:

Code Block
<camelContext id="CamelContextID" xmlns="http://camel.apache.org/schema/spring">
  <route id="myCustomRouteId" >
    <from uri="SourceURI"/>
    <process ref="someProcessorId"/>
    <to uri="TargetURI"/>
  </route>
</camelContext>

Manually Start and Stop Routes

There may be a need for us to manually start or stop a route at any time. We can perform this in Java by invoking the startRoute() and stopRoute() methods on the CamelContext instance. For example, to start the route having the route ID, notAuto, invoke the startRoute() method on the CamelContext instance, context:

Code Block
context.startRoute("notAuto");

To stop the route notAuto, we can invoke the stopRoute() method on our instance:

Code Block
context.stopRoute("nonAuto");

Startup Order

By default, Apache Camel starts up routes in a non-deterministic order. However, in some application situations, it could be vital to control the order of the route startup. Each route must be assigned a unique startup order value. You can choose any positive integer value that is less than 1000

To control the startup order, we can use startupOrder() command in the Java DSL. It will accept a positive integer value as its argument and the route with the lowest integer value starts first:

Code Block
from("jetty:http://fooserver:8080")
    .routeId("one")
    .startupOrder(2)
    .to("seda:buffer");

from("seda:buffer")
    .routeId("two")
    .startupOrder(1)
    .to("mock:result");

// This route's startup order is unspecified
from("jms:queue:foo").to("jms:queue:bar");

NOTE: These two routes are linked together via the endpoint of seda:buffer. we can guarantee that the first route segment starts after the second route segment by using the startup orders (2 and 1 respectively)

Or in Spring XML:

Code Block
<route id="one" startupOrder="2">
    <from uri="jetty:http://fooserver:8080"/>
    <to uri="seda:buffer"/>
</route>

<route id="two" startupOrder="1">
    <from uri="seda:buffer"/>
    <to uri="mock:result"/>
</route>

<!-- This route's startup order is unspecified -->
<route>
    <from uri="jms:queue:foo"/>
    <to uri="jms:queue:bar"/>
</route>

NOTE: Each route must be assigned a unique startup order value. You can choose any positive integer value that is less than 1000

Shutdown Order

When we our instance is shutting down, Apache Camel controls the shutdown sequence using a pluggable shutdown strategy. This strategy implements the following shutdown sequence:

  1. All Routes are shut down in the reverse of the start-up order.

  2. In normal situations, the shutdown strategy waits until the currently active exchanges have finished processing.

  3. Shutdown sequence is bound by a timeout (default of 300 seconds). If the shutdown sequence exceeds this timeout, the shutdown strategy will force shutdown to occur, even if some tasks are still running.

Shutdown Sequence of Routes

By default our routes are shut down in the reverse sequence of the start-up order. That is, when a start-up order is defined using the startupOrder() command (in Java DSL) or startupOrder attribute (in XML DSL), the first route to shut down is the route with the highest integer value assigned by the start-up order.

Shut Down Running Tasks

There may be situations where a route is still processing messages and if a route is still processing messages when the shutdown starts, the shutdown strategy normally waits until the currently active exchange has finished processing before shutting down the route.

We are able to configure this behavior on each route using the shutdownRunningTask option. There are two possible options here:

  • ShutdownRunningTask.CompleteCurrentTaskOnly(Default)

Usually, a route operates on just a single message at a time, so you can safely shut down the route after the current task has been completed.

  • ShutdownRunningTask.CompleteAllTasks

We should specify this option in order to shut down situations where we have batch consumers processing. Some consumer endpoints (for example, File, FTP, Mail, iBATIS, and JPA) operate on a batch of messages at a time. For these types of endpoints, it is better to wait until all of the messages in the current batch have been completed.

To shut down a File consumer endpoint gracefully, you should specify the CompleteAllTasks option in the Java DSL as below:

Code Block
public void configure() throws Exception {
    from("file:target/pending")
        .routeId("one").startupOrder(2)
        .shutdownRunningTask(ShutdownRunningTask.CompleteAllTasks)
        .delay(1000).to("seda:foo");

    from("seda:foo")
        .routeId("two").startupOrder(1)
        .to("mock:bar");
}

Or, in the XML DSL:

Code Block
<!-- let this route complete all its pending messages when asked to shut down -->
    <route id="one"
           startupOrder="2"
           shutdownRunningTask="CompleteAllTasks">
        <from uri="file:target/pending"/>
        <delay><constant>1000</constant></delay>
        <to uri="seda:foo"/>
    </route>

Shutdown Timeout

As mentioned earlier, the shutdown timeout has a default value of 300 seconds. We can change the value of the timeout by invoking the setTimeout() method on the shutdown strategy. As an illustration, we can change the timeout value to 600 seconds:

Code Block
// context = CamelContext instance
context.getShutdownStrategy().setTimeout(600);