Task 生命周期

在深入了解创建任务的细节之前,我们需要了解Spring Cloud Data Flow环境中任务的典型生命周期:

1. 创建 Task Applications

虽然Spring Cloud Task确实提供了许多开箱即用的应用程序(在spring-cloud-task-app-starters),但大多数任务应用程序都需要自定义开发。要创建自定义任务应用程序:

  1. 使用Spring Initializer创建一个新项目,确保选择以下启动器:

    1. Cloud Task:依赖是基于spring-cloud-starter-task

    2. JDBC:依赖是基于spring-jdbc

    3. Select your database dependency:选择Data Flow Stream 当前使用的数据库依赖关系。例如:H2

  2. 在新项目中,创建一个新的 Class 作为主类,如下所示:

    @EnableTask
    @SpringBootApplication
    public class MyTask {
        public static void main(String[] args) {
    		SpringApplication.run(MyTask.class, args);
    	}
    }
  3. 您的应用程序中需要一个或多个CommandLineRunnerApplicationRunner实现,才可以使用这个类。您既可以实现自己的,也可以使用Spring Boot提供的。

  4. 使用Spring Boot将应用程序打包到一个über jar中是依照 Spring Boot conventions 标准。打包的 Applicaions 可以注册和部署,如下所示

1.1. Task 数据库配置

当您在外部运行 Task (即从命令行),并且希望Spring Cloud Data Flow 在其UI中显示任务执行时,请确保两者使用的是同一个数据源。默认情况下,Spring Cloud Task 使用一个本地H2实例,并将执行记录到 Spring Cloud Data Flow 使用的数据库中。

2 注册 Task Applications

您可以在Spring Cloud Data Flow Shell 中使用 app register命令向App Registry注册 Task Applications 。您必须提供一个唯一的 Name 和一个可以解析为 Applications 的URI。对于 Type ,请指定为"task"。下面的列表显示了三个例子:

dataflow:>app register --name task1 --type task --uri maven://com.example:mytask:1.0.2

dataflow:>app register --name task2 --type task --uri file:///Users/example/mytask-1.0.2.jar

dataflow:>app register --name task3 --type task --uri https://example.com/mytask-1.0.2.jar

maven模式下提供URI时,格式应符合以下要求:

maven://<groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>

如果您想一次注册多个应用程序,可以将它们存储在属性文件中,其中Key的格式为<type>.<name>,值为URI。例如:

task.foo=file:///tmp/foo-1.2.1.BUILD-SNAPSHOT.jar
task.bar=file:///tmp/bar-1.2.1.BUILD-SNAPSHOT.jar

然后,您可以使用app import命令并使用通过--uri指定属性文件的位置,如下所示:

app import --uri file:///tmp/task-apps.properties

为了方便起见,我们为所有开箱即用的 Task Applications Starts 提供了带有Applications URI(maven和docker都适用)的静态文件。您可以指向此文件并批量导入所有 Applications URI。否则,如本章前面所述,您可以单独注册它们,或者拥有您自己的自定义属性文件,其中只包含所需的 Applications URI。建议在自定义文件中将Applications 集中在列表中。

下表列出了可用的静态属性文件:

例如,如果你想批量注册所有开箱即用的Task Applications ,你可以使用以下命令:

dataflow:>app import \
--uri https://dataflow.spring.io/Dearborn-SR1-task-applications-maven

您还可以设置--local选项(默认情况下为TRUE)以指示是否应在shell进程本身内解析属性文件。如要从 Data Flow Server 解析位置,请指定--localfalse

使用app register或时app import,如果Task Applications 提供了一个已经注册过的 Name 和 Version ,则默认情况下不会覆盖它。如果要更换其他uri或者uri-metadata位置覆盖已经注册过的Task Applications,请设置--force选项。

在某些情况下,资源在服务器端解析。在其他情况下,URI被传递给运行时容器实例,并在其中解析它。有关详细信息,请参阅 Data Flow Server 的文档。

3. 创建 Task Definition

通过提供应用于 Task 的 --definition 执行的参数,可以从Task Applications 创建 Task Definition 。可以通过 RESTful API 或 shell 创建Task Definition 。要使用 shell 创建 Task Definition ,可以使用task create命令创建Task Definition,如下例所示:

dataflow:>task create mytask --definition "timestamp --format=\"yyyy\""
Created new task 'mytask'

Task Definition 的列表可以通过RESTful API或shell获得。要使用shell获取 Task Definition 列表,请使用task list命令。

4. 启动 Task

可以通过RESTful API或shell启动一个临时任务。要通过shell启动一个的任务,可以使用task launch命令,如下面的示例所示:

dataflow:>task launch mytask
Launched task 'mytask'

当 Task 启动时,可以在启动时设置arguments作为命令行参数传递给Task Applications 任何属性,如下:

dataflow:>task launch mytask --arguments "--server.port=8080 --custom=value"

参数需要使用space分隔值。

可以通过使用——properties属性对TaskLauncher进行配置。该属性的格式是以逗号分隔的字符串,前缀为app..。作为Applications 属性传递给 TaskLauncher。如何将它们如何传递到 Task Applications 是取决于如何部署实现的。如果属性的前缀是deployer而不是app,那么它将作为部署时的属性传递给TaskLauncher

dataflow:>task launch mytask --properties "deployer.timestamp.custom1=value1,app.timestamp.custom2=value2"

4.1. Application properties

每个 Applications 都可以自定义配置 peoperties。例如,timestamp可以设置 format 属性进行格式化输出的默认值配置。

dataflow:> task create \
--definition "timestamp --format=\"yyyy\"" \
--name printTimeStamp

这个timestamp配置方式实际上和timestamp.format配置相同 。Data Flow 新增简写形式方式format而未使用timestamp.format。同样也可以使用longhand版本,如以下示例所示:

dataflow:> task create \
--definition "timestamp --timestamp.format=\"yyyy\"" \
--name printTimeStamp

这个简写行为将在 Whitelisting application properties 一节中进行更多讨论。如果使用 registered application property metadata ,则可以使用shell中的 tab 功能获取候选属性名称列表,输入-- 后按tab

shell为应用程序属性提供了Tab补全。shell命令 app info --name <appName> --type <appType> 可以提示所有支持的文档。

<appType> 支持的配置为 task

4.2. 公共 Application properties

除了通过 DSL 进行配置之外,Spring Cloud Data Flow 还提供了一种机制,用于为其启动的所有Task Applications 设置公共属性。可以通过添加spring.cloud.dataflow.applicationProperties.task来完成。在通过Data Flow Server 服务启动 Applications 时,会将所有属性传递给启动实例。

例如,通过使用以下选项启动 Data Flow server ,可以将所有已启动的Applications 配置属性prop1prop2:

--spring.cloud.dataflow.applicationProperties.task.prop1=value1
--spring.cloud.dataflow.applicationProperties.task.prop2=value2

将导致属性,prop1=value1prop2=value2传递给所有已启动的Applications。

此机制配置的属性优先级低于 Task 部署时的属性。如果在Task 启动时指定具有相同键的属性,则会被部署时属性值覆盖。

4.5. Task 启动时的最大并发限制

Spring Cloud Data Flow允许用户为每个平台限制最大并发运行Task 数,以防止IaaS /硬件资源饱和。默认情况下,所有平台的限制都被设置为20。如果平台实例上并发运行的 Task 数量大于或等于限制,则下一个任务启动请求会失败,并将通过RESTful API、Shell或UI返回一条错误消息。可以通过设置相应的部署属性配置spring.cloud.dataflow.task.platform.<platform-type>.accounts[<account-name>].maximum-concurrent-tasks 来为平台实例配置此限制,其中<account-name>是平台名称(如果没有则为默认值 default)。<platform-type>指当前的部署模式:localcloudfoundrykubernetes

每平台的 TaskLauncher 实现可以通过查询底层平台(如果可行)的运行时状态来确定当前正在执行的 Task 的数量。每个平台都有不同的方式来区分 Task

例如,在本地主机上启动任务使用LocalTaskLauncher。LocalTask​​Launcher 为每个启动的请求创建一个进程,并在内存中跟踪这些进程。在这种情况下,我们不会查询底层操作系统,因为这种识别 Task 的方式是不可行的。

对于Cloud Foundry,Task 是其部署模型所支持的核心。所有 Task 的运行中,完成或失败状态均可通过API直接获得。这意味着对应帐户或组织的空间下,每个正在运行的 Task 容器都会统计进入运行中的计数器中,无论它是使用Spring Cloud Data Flow启动还是CloudFoundryTaskLauncher直接调用。

对于Kubernetes,通过KubernetesTaskLauncher启动一个任务,如果成功,将会运行一个pod,我们希望它能够返最终完成或者失败的状态。但是在这种环境中,通常下没有简单的方法来识别和 Task 相对应的pod。出于这个原因,我们只统计由KubernetesTaskLauncher启动的pod。Task 启动器在pod的元数据中可以设计标签task-name,因此我们会根据此标签的内容过滤所有正在运行的pod。

4.6. Reviewing Task Executions

一旦启动Task ,它的状态就会在数据库中存储下来。其中包括:

  • Task Name

  • Start Time

  • End Time

  • Exit Code

  • Exit Message

  • Last Updated Time

  • Parameters

用户可以通过 RESTful API 或 shell 检查任务执行的状态。要通过shell显示最新的任务执行情况,请使用task execution list命令。

如果要指定获取一个 task definition 的执行列表,请添加--name参数指定名称task execution list --name foo。要查询任务执行的详细信息,请使用task execution status 并且指定Task id,task execution status --id 549

4.7. Destroying a Task Definition

销毁 Task Definition 会从对应的数据库中删除该定义。这可以通过RESTful API或shell来完成。要通过shell销毁Task ,请使用该task destroy命令,如以下示例所示:

dataflow:>task destroy mytask
Destroyed task 'mytask'

要通过shell销毁所有任务,请使用task all destroy以下示例中所示的命令:

dataflow:>task all destroy
Really destroy all tasks? [y, n]: y
All tasks destroyed

或者使用force命令:

dataflow:>task all destroy --force
All tasks destroyed

任务的启动以及执行信息仍会保存在数据库中。

4.8. Validating a Task

有时,在注册 Applications 时,task definition 中会包含一个或多个Application ,其中包含无效的URI。这可能是由于在 app 注册时输入的URI无效,或者 app 已经从存储库中移除。要验证 Task 中包含的所有Applications URL是否用,应使用validate命令。例如:

dataflow:>task validate time-stamp
╔══════════╤═══════════════╗
║Task Name │Task Definition║
╠══════════╪═══════════════╣
║time-stamp│timestamp      ║
╚══════════╧═══════════════╝


time-stamp is a valid task.
╔═══════════════╤═════════════════╗
║   App Name    │Validation Status║
╠═══════════════╪═════════════════╣
║task:timestamp │valid            ║
╚═══════════════╧═════════════════╝

在上面的示例中,我们验证 Task time-stamp 。我们看到task:timestamp Applications 是有效的。现在让我们看看如果我们有一个带有无效URI的注册 Applications 的会如何。

dataflow:>task validate bad-timestamp
╔═════════════╤═══════════════╗
║  Task Name  │Task Definition║
╠═════════════╪═══════════════╣
║bad-timestamp│badtimestamp   ║
╚═════════════╧═══════════════╝


bad-timestamp is an invalid task.
╔══════════════════╤═════════════════╗
║     App Name     │Validation Status║
╠══════════════════╪═════════════════╣
║task:badtimestamp │invalid          ║
╚══════════════════╧═════════════════╝

在这种情况下,Spring Cloud Data Flow 提示 invalid,因为task:badtimestamp 的 URI 是错误的。

Last updated

Was this helpful?