camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Graceful Shutdown
Date Sat, 26 Dec 2009 15:02:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Graceful+Shutdown">Graceful
Shutdown</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="GracefulShutdown-GracefulShutdown"></a>Graceful Shutdown</h2>
<p><b>Available as of Camel 2.2</b></p>

<p>Camel now supports a pluggable shutdown strategy using <tt>org.apache.camel.spi.ShutdownStrategy</tt>.
Its responsible for shutting down routes in a graceful manner. The other resources will still
be handled by <a href="/confluence/display/CAMEL/CamelContext" title="CamelContext">CamelContext</a>
to shutdown. This leaves the problem at hand with properly shutting down all the routes in
a reliable manner to the <tt>ShutdownStrategy</tt>.</p>

<p>Camel provides a default strategy in the <tt>org.apache.camel.impl.DefaultShutdownStrategy</tt>
which is capable of doing that. </p>

<h3><a name="GracefulShutdown-DefaultShutdownStrategy"></a>DefaultShutdownStrategy</h3>
<p>The default strategy will graceful shutdowns routes:</p>
<ul class="alternate" type="square">
	<li>in the same order they where started</li>
	<li>let pending and current in flight exchanges run to completion before shutting down</li>
	<li>using a timeout of 300 seconds which then forces a shutdown now</li>
</ul>


<p>You can configure the timeout and whether it should shutdown now remainder routes
when the timeout occurred or ignore. See the setters on the class.</p>

<p>It will output to log the progress during graceful shutdown as shown in an example
below</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
2009-12-20 10:56:53,055 [main           ] INFO  DefaultCamelContext            - Apache Camel
 (CamelContext:camel-1) is stopping
2009-12-20 10:56:53,056 [main           ] INFO  DefaultShutdownStrategy        - Starting
to graceful shutdown routes (timeout 300 seconds)
2009-12-20 10:56:53,059 [1: ShutdownTask] INFO  DefaultShutdownStrategy        - Waiting as
there are still 5 inflight exchanges to complete before we can shutdown
2009-12-20 10:56:54,060 [1: ShutdownTask] INFO  DefaultShutdownStrategy        - Waiting as
there are still 4 inflight exchanges to complete before we can shutdown
2009-12-20 10:56:55,061 [1: ShutdownTask] INFO  DefaultShutdownStrategy        - Waiting as
there are still 3 inflight exchanges to complete before we can shutdown
2009-12-20 10:56:56,065 [1: ShutdownTask] INFO  DefaultShutdownStrategy        - Waiting as
there are still 2 inflight exchanges to complete before we can shutdown
2009-12-20 10:56:57,066 [1: ShutdownTask] INFO  DefaultShutdownStrategy        - Waiting as
there are still 1 inflight exchanges to complete before we can shutdown
2009-12-20 10:56:58,069 [main           ] INFO  DefaultShutdownStrategy        - Graceful
shutdown of routes complete in 5 seconds.
2009-12-20 10:56:58,072 [main           ] INFO  DefaultInflightRepository      - Shutting
down with no inflight exchanges.
2009-12-20 10:56:58,077 [main           ] INFO  DefaultCamelContext            - Apache Camel
 (CamelContext:camel-1) stopped
</pre>
</div></div>

<p>Notice how it waits while there are inflight exchanges still be processed before
it can shutdown.</p>

<h3><a name="GracefulShutdown-Controllingorderingofroutes"></a>Controlling
ordering of routes</h3>
<p>You can configure the order in which routes should be started, and thus also the
same order they are being shutdown.<br/>
See more at <a href="/confluence/display/CAMEL/Configuring+route+startup+ordering+and+autostartup"
title="Configuring route startup ordering and autostartup">Configuring route startup ordering
and autostartup</a>.</p>

<h3><a name="GracefulShutdown-Finegrainedconfiguration"></a>Fine grained
configuration</h3>
<p>You can control two areas that influences graceful shutdown in the Camel routing:</p>
<ul class="alternate" type="square">
	<li><tt>ShutdownRoute</tt></li>
	<li><tt>ShutdownRunningTaks</tt></li>
</ul>


<p>These options can be configured on two scopes: <tt>context</tt> and <tt>route</tt>.
Where a route will fallback to the <tt>context</tt> scoped option, if not explicit
configured. (same principle as <a href="/confluence/pages/createpage.action?spaceKey=CAMEL&amp;title=ErrorHandler&amp;linkCreation=true&amp;fromPageId=9373969"
class="createlink">ErrorHandler</a> etc.).</p>

<h4><a name="GracefulShutdown-ShutdownRoute"></a>ShutdownRoute</h4>
<p>This option can control how a given route should act during graceful shutdown. It
has two values <tt>Default</tt> and <tt>Defer</tt>. The <tt>Default</tt>
is obviously the default option which lets Camel shutdown the route as early as possible.
The <tt>Defer</tt> is used to defer shutting down this route to a later stage.
This is useable if other routes is dependent upon it. For example an internal route which
other routes reuse.</p>

<p>For example in the route below we have two routes, where route 1 is dependent upon
route 2. At shutdown we want route 1 to complete all its current messages and we also want
the 2nd route to do this as well. So we can mark both routes to <tt>Defer</tt>
but since route 1 is a <a href="/confluence/display/CAMEL/SEDA" title="SEDA">SEDA</a>
based route its <tt>Defer</tt> by default (it uses <tt>ShutdownAware</tt>).</p>

<p>A Java DSL based example to defer shutting down the 2nd route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> void configure()
<span class="code-keyword">throws</span> Exception {
    from(<span class="code-quote">"seda:foo"</span>)
        .startupOrder(1)
        .delay(1000).to(<span class="code-quote">"file:<span class="code-comment">//target/deferred"</span>);
</span>
    <span class="code-comment">// use file component to transfer files from route 1
-&gt; route 2 as it
</span>    <span class="code-comment">// will normally suspend, but by deferring
<span class="code-keyword">this</span> we can let route 1
</span>    <span class="code-comment">// complete <span class="code-keyword">while</span>
shutting down
</span>    from(<span class="code-quote">"file:<span class="code-comment">//target/deferred"</span>)
</span>        <span class="code-comment">// defer shutting down <span class="code-keyword">this</span>
route as the 1st route depends upon it
</span>        .startupOrder(2).shutdownRoute(Defer)
        .to(<span class="code-quote">"mock:bar"</span>);
}
</pre>
</div></div>

<p>The same route in Spring XML would be:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;camelContext id=<span
class="code-quote">"camel"</span> xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route startupOrder=<span class="code-quote">"1"</span>&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"seda:foo"</span>/&gt;</span>
        <span class="code-tag">&lt;delay&gt;</span><span class="code-tag">&lt;constant&gt;</span>1000<span
class="code-tag">&lt;/constant&gt;</span><span class="code-tag">&lt;/delay&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"file://target/deferred"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- defer shutting
down this route as the first route is depend upon it --&gt;</span></span>
    <span class="code-tag">&lt;route startupOrder=<span class="code-quote">"2"</span>
shutdownRoute=<span class="code-quote">"Defer"</span>&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"file://target/deferred"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:bar"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Defer shutting down internal
routes only</b><br /><p>Its best to only defer shutting down internal routes
only. As <b>public</b> routes should shutdown as quickly as possible otherwise
it will just keep intake new messages which will delay the shutdown processor. Or even have
it timeout if a lot of new messages keep coming in.</p></td></tr></table></div>

<h4><a name="GracefulShutdown-ShutdownRunningTask"></a>ShutdownRunningTask</h4>
<p>This option control how a given route consumer acts during shutdown. Most route consumer
will only operate on a single task (message), however the <a href="/confluence/display/CAMEL/Batch+Consumer"
title="Batch Consumer">Batch Consumer</a> can operate on many messages (in a batch).
This option is for those kind of consumers. By default it uses the option <tt>CompleteCurrentTaskOnly</tt>
which mean that the current <em>in progress</em> task (message) will be completed
and then the consumer will shutdown. The other option <tt>CompleteAllTasks</tt>
allows the consumer to complete all the tasks (messages) before shutting down. For example
a <a href="/confluence/display/CAMEL/File2" title="File2">File</a> consumer will
process all the pending files it has picked up before shutting down.</p>

<p>A Java DSL based example to complete all messages during shutting down the first
route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> void configure()
<span class="code-keyword">throws</span> Exception {
    from(url)
        <span class="code-comment">// let it complete all tasks during shutdown
</span>        .shutdownRunningTask(ShutdownRunningTask.CompleteAllTasks)
        .delay(1000).to(<span class="code-quote">"seda:foo"</span>);

    from(<span class="code-quote">"seda:foo"</span>).to(<span class="code-quote">"mock:bar"</span>);
}
</pre>
</div></div>

<p>The same route in Spring XML would be:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;camelContext id=<span
class="code-quote">"camel"</span> xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag"><span class="code-comment">&lt;!-- let this route
complete all its pending messages when asked to shutdown --&gt;</span></span>
    <span class="code-tag">&lt;route startupOrder=<span class="code-quote">"1"</span>
shutdownRunningTask=<span class="code-quote">"CompleteAllTasks"</span>&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"file:target/pending"</span>/&gt;</span>
        <span class="code-tag">&lt;delay&gt;</span><span class="code-tag">&lt;constant&gt;</span>1000<span
class="code-tag">&lt;/constant&gt;</span><span class="code-tag">&lt;/delay&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"seda:foo"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>

    <span class="code-tag">&lt;route startupOrder=<span class="code-quote">"2"</span>&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"seda:foo"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:bar"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<h3><a name="GracefulShutdown-JMXmanaged"></a>JMX managed</h3>
<p>The <tt>ShutdownStrategy</tt> is JMX aware as well so you can manage
it from a JMX console. For example you can change the timeout value.</p>

<h3><a name="GracefulShutdown-Developerrelated"></a>Developer related</h3>
<p>If you develop your own Camel component or want to implement your own shutdown strategy
then read this section for details.</p>

<h4><a name="GracefulShutdown-ShutdownStrategy"></a>ShutdownStrategy</h4>
<p>You can implement your own strategy to control the shutdown by implementing the <tt>org.apache.camel.spi.ShutdownStrategy</tt>
and the set it on the <tt>CamelContext</tt> using the <tt>setShutdownStrategy</tt>
method.</p>

<p>When using Spring XML you then just define a spring bean which implements the <tt>org.apache.camel.spi.ShutdownStrategy</tt>
and Camel will lookup it up at startup and use it instead of its default. See more at <a
href="/confluence/display/CAMEL/Advanced+configuration+of+CamelContext+using+Spring" title="Advanced
configuration of CamelContext using Spring">Advanced configuration of CamelContext using
Spring</a>.</p>

<h4><a name="GracefulShutdown-ShutdownAware"></a>ShutdownAware</h4>
<p>The interface <tt>org.apache.camel.spi.ShutdownAware</tt> is an optional
interface consumers can implement to have fine grained control during shutdown. The <tt>ShutdownStrategy</tt>
must be able to deal with consumers which implements this interface. This interface was introduced
to cater for in memory consumers such as <a href="/confluence/display/CAMEL/SEDA" title="SEDA">SEDA</a>
which potentially have a number of pending messages on its internal in memory queues. What
this allows is to let it control the shutdown process to let it complete its pending messages.</p>

<p>The method <tt>getPendingExchangesSize</tt> should return the number
of pending messages which reside on the in memory queues.<br/>
The method <tt>deferShutdown</tt> should return <tt>false</tt> to
defer the shutdown to very last when there are no more pending and inflight messages.</p>

<p><a href="/confluence/display/CAMEL/Batch+Consumer" title="Batch Consumer">Batch
Consumer</a> should implement <tt>ShutdownAware</tt> so they properly supports
the <tt>ShutdownRunningTask</tt> option. See for example <tt>GenericFileConsumer</tt>
for an example.</p>

<h3><a name="GracefulShutdown-SeeAlso"></a>See Also</h3>
<ul class="alternate" type="square">
	<li><a href="/confluence/display/CAMEL/Configuring+route+startup+ordering+and+autostartup"
title="Configuring route startup ordering and autostartup">Configuring route startup ordering
and autostartup</a></li>
	<li><a href="/confluence/display/CAMEL/Advanced+configuration+of+CamelContext+using+Spring"
title="Advanced configuration of CamelContext using Spring">Advanced configuration of CamelContext
using Spring</a></li>
	<li><a href="/confluence/display/CAMEL/User+Guide" title="User Guide">User Guide</a></li>
</ul>

     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Graceful+Shutdown">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=9373969&revisedVersion=9&originalVersion=8">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Graceful+Shutdown?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message