2.9. 控制开始和关闭路由


概述

默认情况下,当 Apache Camel 应用程序(由 CamelContext 实例代表)启动和路由关闭时,路由会自动关闭。对于非关键部署,关闭序列的详细信息通常并不重要。但在生产环境中,对于现有任务在关闭期间应运行,以避免数据丢失,这通常至关重要。您通常还希望控制路由关闭的顺序,因此不会违反依赖项(这将阻止现有任务运行完成)。

因此,Apache Camel 提供了一组功能来支持 正常关闭 应用程序。正常关机可让您完全控制停止和启动路由,使您能够控制路由的关机顺序,并让当前任务完成运行。

设置路由 ID

最好为每个路由分配路由 ID。除了更明确的记录信息和管理功能外,使用路由 ID 可让您对停止和启动路由应用更大的控制。

例如,在 Java DSL 中,您可以通过调用 routeId () 命令将路由 ID myCustomerRouteId 分配给路由:

from("SourceURI").routeId("myCustomRouteId").process(...).to(TargetURI);

在 XML DSL 中,设置 路由 元素的 id 属性,如下所示:

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

禁用自动启动路由

默认情况下,CamelContext 知道的所有路由都会自动启动。如果要手动控制特定路由的启动,但您可能需要为该路由禁用自动启动。

要控制 Java DSL 路由是否自动启动,请调用 autoStartup 命令,使用 布尔值 参数(truefalse)或 String 参数(truefalse)。例如,您可以在 Java DSL 中禁用路由的自动启动,如下所示:

from("SourceURI")
  .routeId("nonAuto")
  .autoStartup(false)
  .to(TargetURI);

您可以通过在路由元素上将 autoStartup 属性设置为 false 来禁用 XML DSL 中的自动启动 路由,如下所示:

<camelContext id="CamelContextID" xmlns="http://camel.apache.org/schema/spring">
  <route id="nonAuto" autoStartup="false">
    <from uri="SourceURI"/>
    <to uri="TargetURI"/>
  </route>
</camelContext>

手动启动和停止路由

您可以通过调用 CamelContext 实例的 startRoute ()stopRoute () 方法,在 Java 中随时启动或停止路由。例如,要启动具有路由 ID 非Auto 的路由,请调用 CamelContext 实例上的 startRoute () 方法,上下文,如下所示:

// Java
context.startRoute("nonAuto");

要停止具有路由 ID 非Auto 的路由,请调用 CamelContext 实例上的 stopRoute () 方法,如下所示:

// Java
context.stopRoute("nonAuto");

路由的启动顺序

默认情况下,Apache Camel 以非确定顺序启动路由。然而,在某些应用程序中,控制启动顺序非常重要。要控制 Java DSL 中的启动顺序,请使用 start Order () 命令,该命令取正整数值作为其参数。最低整数值的路由首先启动,后跟连续更高的启动顺序值的路由。

例如,以下示例中的第一个路由通过 seda:buffer 端点链接在一起。您可以通过分别分配启动顺序(2 和 1),以确保第一个路由片段在第二个路由段 后启动,如下所示:

例 2.5. 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");

或者在 Spring XML 中,您可以通过设置 路由 元素的 start Order 属性来实现相同的效果,如下所示:

例 2.6. 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>

每个路由必须 分配唯一的 启动顺序值。您可以选择任何小于 1000 的正整数值。为 Apache Camel 保留 1000 值和 over,这些值会自动分配给路由,而无需显式启动值。例如,上例中的最后一个路由将自动分配给启动值 1000 (因此,在前两个路由后启动)。

关闭序列

CamelContext 实例关闭时,Apache Camel 会使用可插入的关闭策略来控制 关闭 序列。默认关闭策略实现以下关闭序列:

  1. 路由会根据启动顺序 反向 关闭。
  2. 通常,关闭策略会等待当前活动的交换处理。但是,正在运行的任务的处理是可配置的。
  3. 总体而言,关闭序列使用超时(默认值 300 秒)绑定。如果关闭序列超过这个超时,关闭策略将强制关闭,即使有些任务仍在运行。

路由的关闭顺序

路由会根据启动顺序反向关闭。也就是说,当使用 bootOrder () 命令(在 Java DSL 中)或 startupOrder 属性(在 XML DSL 中)定义启动顺序时,第一个路由是带有启动顺序分配的 最高 整数值的路由,最后要关闭的、使用启动顺序分配的整数值。

例如,在 例 2.5 “Java DSL 中的启动顺序” 中,要关闭的第一个路由部分是 ID 的路由,第一个 路由部分是要关闭的第二个路由部分,其 ID 为 第二个 路由。本例演示了一个常规规则,在关闭路由时应该观察到路由: 公开外部访问使用者端点的路由应关闭第一个,因为这有助于通过路由图形的其余部分调整消息流。

注意

Apache Camel 还提供选项 shutdownRoute (Defer),它可让您指定路由必须处于关闭的最后一个路由中(覆盖启动顺序值)。但是,您很少需要这个选项。这个选项主要是用来替代 Apache Camel (至 2.3)版本的 Apache Camel 的一种临时解决方案,路由会按照 与启动顺序相同的 顺序进行关闭。

关闭路由中运行的任务

如果路由在关闭启动时仍然处理消息,关闭策略通常会等待当前活跃的交换完成处理,然后再关闭路由。可以使用 shutdownRunningTask 选项在每个路由上配置此行为,该选项可采用以下值之一:

ShutdownRunningTask.CompleteCurrentTaskOnly
(默认)"默认 ",路由一次只针对一条信息,因此您可以在当前任务完成后安全关闭路由。
ShutdownRunningTask.CompleteAllTasks
指定这个选项,以正常关闭 批处理消费者。有些消费者端点(如 file、FTP、邮件、iBATIS 和 JPA)一次在消息批处理上运行。对于这些端点,务必要等到当前批处理中的所有消息都已完成。

例如,要正常关闭文件消费者端点,您应该指定 CompleteAllTasks 选项,如以下 Java DSL 片段所示:

// 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");
}

相同的路由可以在 XML DSL 中定义,如下所示:

<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>

关闭超时

关闭超时的默认值为 300 秒。您可以通过在 shutdown 策略上调用 setTimeout () 方法来更改超时值。例如,您可以将超时值改为 600 秒,如下所示:

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

与自定义组件集成

如果您要实施自定义 Apache Camel 组件(也会继承 org.apache.camel.Service 界面),您可以通过实施 org.apache.camel.spi.ShutdownPrepared 接口来请确保您的自定义代码收到关闭通知。这给组件提供了机会执行自定义代码以准备关机。

2.9.1. RouteIdFactory

根据消费者端点,您可以添加 RouteIdFactory,该 RouteIdFactory 可以使用逻辑名称分配路由 ID。

例如,当使用带有 seda 或 direct 组件的路由作为路由输入时,您可能希望使用其名称作为路由 ID,例如:

  • direct:foo- foo
  • seda:bar- bar
  • jms:orders- orders

您可以使用 NodeIdFactory 为路由分配逻辑名称,而不使用自动分配名称。另外,您可以使用路由 URL 的 context-path 作为名称。例如,执行以下命令来使用 RouteIDFactory

context.setNodeIdFactory(new RouteIdFactory());
注意

可以从其余端点获取自定义路由 ID。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.