By default, routes are automatically started when your Fuse Mediation Router application (as
represented by the CamelContext
instance) starts up and routes are
automatically shut down when your Fuse Mediation Router application shuts down. For non-critical
deployments, the details of the shutdown sequence are usually not very important. But in a
production environment, it is often crucial that existing tasks should run to completion
during shutdown, in order to avoid data loss. You typically also want to control the order
in which routes shut down, so that dependencies are not violated (which would prevent
existing tasks from running to completion).
For this reason, Fuse Mediation Router 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.
It is good practice to assign a route ID to each of your routes. As well as making logging messages and management features more informative, the use of route IDs enables you to apply greater control over the stopping and starting of routes.
For example, in the Java DSL, you can assign the route ID,
myCustomerRouteId
, to a route by invoking the routeId()
command
as follows:
from("SourceURI
").routeId("myCustomRouteId").process(...).to(TargetURI
);
In the XML DSL, set the route
element's id
attribute, as
follows:
<camelContext id="CamelContextID
" xmlns="http://camel.apache.org/schema/spring"> <route id="myCustomRouteId" > <from uri="SourceURI
"/> <process ref="someProcessorId"/> <to uri="TargetURI
"/> </route> </camelContext>
By default, all of the routes that the CamelContext knows about at start time will be started automatically. If you want to control the start-up of a particular route manually, however, you might prefer to disable automatic start-up for that route.
For example, you can disable automatic start-up of a route in the Java DSL by invoking
noAutoStartup()
, as follows:
from("SourceURI
").routeId("nonAuto").noAutoStartup().to(TargetURI
);
You can disable automatic start-up of a route in the XML DSL by setting the
autoStartup
attribute to false
on the route
element, as follows:
<camelContext id="CamelContextID
" xmlns="http://camel.apache.org/schema/spring"> <route id="nonAuto" autoStartup="false"> <from uri="SourceURI
"/> <to uri="TargetURI
"/> </route> </camelContext>
You can manually start or stop a route at any time in Java by invoking the
startRoute()
and stopRoute()
methods on the
CamelContext
instance. For example, to start the route having the route ID,
nonAuto
, invoke the startRoute()
method on the
CamelContext
instance, context
, as follows:
// Java context.startRoute("nonAuto");
To stop the route having the route ID, nonAuto
, invoke the
stopRoute()
method on the CamelContext
instance,
context
, as follows:
// Java context.stopRoute("nonAuto");
By default, Apache Camel starts up routes in a non-deterministic order. In some applications,
however, it can be important to control the startup order. To control the startup order in
the Java DSL, use the startupOrder()
command, which takes a positive integer
value as its argument. The route with the lowest integer value starts first, followed by the
routes with successively higher startup order values.
For example, the first two routes in the following example are linked together through
the seda:buffer
endpoint. You can ensure that the first route segment starts
after the second route segment by assigning startup orders (2 and 1
respectively), as follows:
Example 2.3. Startup Order in Java DSL
from("jetty:http://fooserver:8080") .routeId("first") .startupOrder(2) .to("seda:buffer"); from("seda:buffer") .routeId("second") .startupOrder(1) .to("mock:result"); // This route's startup order is unspecified from("jms:queue:foo").to("jms:queue:bar");
Or in Spring XML, you can achieve the same effect by setting the route
element's startupOrder
attribute, as follows:
Example 2.4. Startup Order in XML DSL
<route id="first" startupOrder="2"> <from uri="jetty:http://fooserver:8080"/> <to uri="seda:buffer"/> </route> <route id="second" 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>
Each route must be assigned a unique startup order value. You can choose any positive integer value that is less than 1000. Values of 1000 and over are reserved for Apache Camel, which automatically assigns these values to routes without an explicit startup value. For example, the last route in the preceding example would automatically be assigned the startup value, 1000 (so it starts up after the first two routes).
When a CamelContext
instance is shutting down, Fuse Mediation Router controls the
shutdown sequence using a pluggable shutdown strategy. The default
shutdown strategy implements the following shutdown sequence:
Routes are shut down in the reverse of the start-up order.
Normally, the shutdown strategy waits until the currently active exchanges have finshed processing. The treatment of running tasks is configurable, however.
Overall, the shutdown sequence is bound by a timeout (default, 300 seconds). If the shutdown sequence exceeds this timeout, the shutdown strategy will force shutdown to occur, even if some tasks are still running.
Routes are shut down in the reverse 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 and
the last route to shut down is the route with the lowest integer value
assigned by the start-up order.
For example, in Example 2.3, the first
route segment to be shut down is the route with the ID, first
, and the second
route segment to be shut down is the route with the ID, second
. This example
illustrates a general rule, which you should observe when shutting down routes:
the routes that expose externally-accessible consumer endpoints should be shut
down first, because this helps to throttle the flow of messages through the
rest of the route graph.
![]() | Note |
---|---|
Fuse Mediation Router also provides the option |
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. This behavior can be configured on each route using the
shutdownRunningTask
option, which can take either of the following
values:
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 completed.
ShutdownRunningTask.CompleteAllTasks
Specify this option in order to shut down batch consumers gracefully. Some consumer endpoints (for example, File, FTP, Mail, iBATIS, and JPA) operate on a batch of messages at a time. For these endpoints, it is more appropriate to wait until all of the messages in the current batch have completed.
For example, to shut down a File consumer endpoint gracefully, you should specify the
CompleteAllTasks
option, as shown in the following Java DSL fragment:
// Java
public void configure() throws Exception {
from("file:target/pending")
.routeId("first").startupOrder(2)
.shutdownRunningTask(ShutdownRunningTask.CompleteAllTasks)
.delay(1000).to("seda:foo");
from("seda:foo")
.routeId("second").startupOrder(1)
.to("mock:bar");
}
The same route can be defined in the XML DSL as follows:
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<!-- let this route complete all its pending messages when asked to shut down -->
<route id="first"
startupOrder="2"
shutdownRunningTask="CompleteAllTasks">
<from uri="file:target/pending"/>
<delay><constant>1000</constant></delay>
<to uri="seda:foo"/>
</route>
<route id="second" startupOrder="1">
<from uri="seda:foo"/>
<to uri="mock:bar"/>
</route>
</camelContext>
The shutdown timeout has a default value of 300 seconds. You can change the value of the
timeout by invoking the setTimeout()
method on the shutdown strategy. For
example, you can change the timeout value to 600 seconds, as follows:
// Java // context = CamelContext instance context.getShutdownStrategy().setTimeout(600);