任务
本节详细介绍如何在 Spring Cloud Data Flow 上编排 Spring Cloud Task 应用程序。
如果您刚刚开始使用 Spring Cloud Data Flow,那么在深入了解本节之前,您可能应该阅读“本地”、“Cloud Foundry”或“Kubernetes”的入门指南。
24. 引言
任务应用程序是短暂的,这意味着它故意停止运行,可以按需运行或安排稍后运行。 一个用例可能是抓取网页并写入数据库。
Spring Cloud Task 框架基于 Spring Boot,增加了 Boot 应用程序记录短期应用程序的生命周期事件的能力,例如它何时启动、何时结束和退出状态。
这TaskExecution
文档显示数据库中存储了哪些信息。
Spring Cloud Task 应用程序中代码执行的入口点通常是 Boot 的CommandLineRunner
接口,如本示例所示。
Spring Batch 项目可能是编写短期应用程序的 Spring 开发人员想到的。
Spring Batch 提供了比 Spring Cloud Task 更丰富的功能集,建议在处理大量数据时使用。
一个用例可能是读取许多 CSV 文件,转换每一行数据,并将每个转换后的行写入数据库。
Spring Batch 提供了自己的数据库模式,其中包含有关 Spring Batch 作业执行的更丰富的信息集。
Spring Cloud Task 与 Spring Batch 集成,因此,如果 Spring Cloud Task 应用程序定义了 Spring BatchJob
,则在 Spring Cloud Task 和 Spring Cloud Batch 执行表之间创建链接。
在本地计算机上运行数据流时,任务将在单独的 JVM 中启动。
在 Cloud Foundry 上运行时,使用 Cloud Foundry 的任务功能启动任务。在 Kubernetes 上运行时,任务是通过使用Pod
或Job
资源。
25. 任务的生命周期
在深入了解创建任务的详细信息之前,您应该了解 Spring Cloud Data Flow 上下文中任务的典型生命周期:
25.1. 创建任务应用程序
Spring Cloud Dataflow 提供了几个开箱即用的任务应用程序(timestamp-task 和 timestamp-batch),但大多数任务应用程序都需要自定义开发。
要创建自定义任务应用程序,请执行以下作:
-
使用 Spring 初始值设定项创建一个新项目,确保选择以下Starters:
-
Cloud Task
:此依赖项是spring-cloud-starter-task
. -
JDBC
:此依赖项是spring-jdbc
起动机。 -
选择数据库依赖项:输入数据流当前使用的数据库依赖项。例如:
H2
.
-
-
在新项目中,创建一个新类作为主类,如下所示:
@EnableTask @SpringBootApplication public class MyTask { public static void main(String[] args) { SpringApplication.run(MyTask.class, args); } }
-
对于本课程,您需要一个或多个
CommandLineRunner
或ApplicationRunner
应用程序中的实现。您可以实现自己的或使用 Spring Boot 提供的(例如,有一个用于运行批处理作业)。 -
使用 Spring Boot 将应用程序打包到 über jar 中是通过标准 Spring Boot 约定完成的。 可以如下所述注册和部署打包的应用程序。
25.1.1. 任务数据库配置
启动任务应用程序时,请确保 Spring Cloud Data Flow 使用的数据库驱动程序也是对任务应用程序的依赖项。 例如,如果您的 Spring Cloud Data Flow 设置为使用 Postgresql,请确保任务应用程序也将 Postgresql 作为依赖项。 |
当您在外部(即从命令行)运行任务并希望 Spring Cloud Data Flow 在其 UI 中显示 TaskExecutions 时,请确保在它们之间共享通用数据源设置。 默认情况下,Spring Cloud Task 使用本地 H2 实例,执行记录到 Spring Cloud Data Flow 使用的数据库中。 |
25.2. 注册任务应用程序
您可以使用 Spring Cloud Data Flow Shell 向 App Registry 注册任务应用程序app register
命令。
必须提供可解析为应用程序项目的唯一名称和 URI。对于类型,请指定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
在提供 URI 时maven
方案,格式应符合以下要求:
maven://<groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
如果您想一次注册多个应用程序,您可以将它们存储在属性文件中,其中键的格式为<type>.<name>
值是 URI。
例如,以下列表将是一个有效的属性文件:
task.cat=file:///tmp/cat-1.2.1.BUILD-SNAPSHOT.jar
task.hat=file:///tmp/hat-1.2.1.BUILD-SNAPSHOT.jar
然后你可以使用app import
命令,并使用--uri
选项,如下所示:
app import --uri file:///tmp/task-apps.properties
例如,如果要在单个作中注册数据流附带的所有任务应用程序,可以使用以下命令执行此作:
dataflow:>app import --uri https://dataflow.spring.io/task-maven-latest
您还可以将--local
选项(即TRUE
默认情况下),以指示是否应在 shell 进程本身中解析属性文件位置。
如果应从数据流服务器进程中解析位置,请指定--local false
.
当使用任一app register
或app import
,如果任务应用程序已注册
提供的名称和版本,默认情况下不会覆盖。如果您想覆盖
具有不同uri
或uri-metadata
location,包括--force
选择。
在某些情况下,资源在服务器端解析。 在其他情况下,URI 将传递到运行时容器实例,并在其中进行解析。 有关更多详细信息,请参阅每个数据流服务器的特定文档。 |
25.3. 创建任务定义
您可以通过提供定义名称以及
应用于任务执行的属性。您可以通过
RESTful API 或 shell。要使用 shell 创建任务定义,请使用task create
命令创建任务定义,如以下示例所示:
dataflow:>task create mytask --definition "timestamp --format=\"yyyy\""
Created new task 'mytask'
您可以通过 RESTful API 或 shell 获取当前任务定义的列表。
若要使用 shell 获取任务定义列表,请使用task list
命令。
25.3.1. 最大任务定义名称长度
任务定义名称的最大字符长度取决于平台。
有关资源命名的详细信息,请参阅平台文档。 本地平台将任务定义名称存储在最大大小为 255 的数据库列中。 |
Kubernetes 裸 Pod | Kubernetes 作业 | 云代工厂 | 当地 |
---|---|---|---|
63 |
52 |
63 |
255 |
25.3.2. 自动创建任务定义
从 2.3.0 版开始,您可以通过将 Data Flow 服务器配置为自动创建任务定义spring.cloud.dataflow.task.autocreate-task-definitions
自true
.
这不是默认行为,而是为了方便起见而提供的。
启用此属性后,任务启动请求可以将已注册的任务应用程序名称指定为任务名称。
如果已注册任务应用程序,则服务器将根据需要创建一个仅指定应用程序名称的基本任务定义。这消除了类似于以下作的手动步骤:
dataflow:>task create mytask --definition "mytask"
您仍然可以为每个任务启动请求指定命令行参数和部署属性。
25.4. 启动任务
可以通过 RESTful API 或 shell 启动临时任务。
要通过 shell 启动临时任务,请使用task launch
命令,如以下示例所示:
dataflow:>task launch mytask
Launched task 'mytask'
启动任务时,可以设置在启动任务时需要作为命令行参数传递给任务应用程序的任何属性,如下所示:
dataflow:>task launch mytask --arguments "--server.port=8080 --custom=value"
参数需要作为空格分隔值传递。 |
您可以传入用于TaskLauncher
使用--properties
选择。
此选项的格式是以逗号分隔的属性字符串,前缀为app.<task definition name>.<property>
.
属性传递给TaskLauncher
作为应用程序属性。
由实现来选择如何将它们传递到实际任务应用程序中。
如果属性前缀为deployer
而不是app
,它被传递给TaskLauncher
作为部署属性,其含义可能是TaskLauncher
具体实施。
dataflow:>task launch mytask --properties "deployer.timestamp.custom1=value1,app.timestamp.custom2=value2"
25.4.1. 应用程序属性
每个应用程序都采用属性来自定义其行为。例如,timestamp
任务format
设置建立与默认值不同的输出格式。
dataflow:> task create --definition "timestamp --format=\"yyyy\"" --name printTimeStamp
这timestamp
属性实际上与timestamp.format
时间戳应用程序指定的属性。
数据流添加了使用速记表单的功能format
而不是timestamp.format
.
您也可以指定长手版本,如以下示例所示:
dataflow:> task create --definition "timestamp --timestamp.format=\"yyyy\"" --name printTimeStamp
流应用程序属性部分详细讨论了此速记行为。
如果已注册应用程序属性元数据,则可以在键入后在 shell 中使用制表符补全来获取候选属性名称的列表。--
shell 为应用程序属性提供制表符补全。这app info --name <appName> --type <appType>
shell 命令为所有受支持的属性提供了其他文档。支持的任务<appType>
是task
.
在 Kubernetes 上重新启动 Spring Batch Jobs 时,必须使用shell 或boot . |
Kubernetes 上包含敏感信息的应用程序属性
启动某些属性可能包含敏感信息的任务应用程序时,请使用shell
或boot
作为entryPointStyle
.这是因为exec
(默认)将所有属性转换为命令行参数,因此,在某些环境中可能不安全。
25.4.2. 常见应用程序属性
除了通过 DSL 进行配置外,Spring Cloud Data Flow 还提供了一种机制来设置它启动的所有任务应用程序通用的属性。
您可以通过添加以spring.cloud.dataflow.applicationProperties.task
启动服务器时。
然后,服务器将所有属性(不带前缀)传递给它启动的实例。
例如,您可以将所有已启动的应用程序配置为使用prop1
和prop2
属性,方法是使用以下选项启动数据流服务器:
--spring.cloud.dataflow.applicationProperties.task.prop1=value1
--spring.cloud.dataflow.applicationProperties.task.prop2=value2
这会导致prop1=value1
和prop2=value2
属性。
使用此机制配置的属性的优先级低于任务部署属性。
如果在任务启动时指定了具有相同键的属性(例如,app.trigger.prop2 覆盖公共属性)。 |
25.5. 限制并发任务启动次数
Spring Cloud Data Flow 允许用户限制每个配置平台并发运行任务的最大数量,以防止 IaaS 或硬件资源饱和。
默认情况下,限制设置为20
适用于所有支持的平台。如果平台实例上并发运行的任务数大于或等于限制,则下一个任务启动请求失败,并通过 RESTful API、Shell 或 UI 返回错误消息。
您可以通过设置相应的部署器属性spring.cloud.dataflow.task.platform.<platform-type>.accounts[<account-name>].maximumConcurrentTasks
哪里<account-name>
是已配置平台帐户的名称(default
如果没有显式配置帐户)。
这<platform-type>
指当前支持的部署器之一:local
或kubernetes
.为cloudfoundry
,则属性为spring.cloud.dataflow.task.platform.<platform-type>.accounts[<account-name>].deployment.maximumConcurrentTasks
.(区别在于deployment
已添加到路径中)。
这TaskLauncher
如果可能,每个受支持平台的实现通过查询底层平台的运行时状态来确定当前正在运行的任务的数量。识别task
因平台而异。
例如,在本地主机上启动任务会使用LocalTaskLauncher
.LocalTaskLauncher
为每个启动请求运行一个进程,并在内存中跟踪这些进程。在这种情况下,我们不查询底层作系统,因为以这种方式识别任务是不切实际的。
对于 Cloud Foundry 来说,任务是其部署模型支持的核心概念。所有任务的状态)可直接通过 API 获得。
这意味着帐户组织和空间中的每个正在运行的任务容器都包含在运行执行计数中,无论它是通过使用 Spring Cloud Data Flow 还是通过调用CloudFoundryTaskLauncher
径直。
对于 Kubernetes,通过KubernetesTaskLauncher
,如果成功,则会导致正在运行的 Pod,我们预计该 Pod 最终会完成或失败。
在此环境中,通常没有简单的方法来识别与任务相对应的 Pod。
因此,我们只计算由KubernetesTaskLauncher
.
由于任务Starters提供了task-name
标签,我们会根据此标签的存在过滤所有正在运行的 Pod。
25.6. 查看任务执行
启动任务后,任务的状态将存储在关系数据库中。状态 包括:
-
任务名称
-
开始时间
-
结束时间
-
退出代码
-
退出消息
-
最后更新时间
-
参数
您可以通过 RESTful API 或 shell 检查任务执行的状态。
要通过 shell 显示最新的任务执行,请使用task execution list
命令。
要仅获取一个任务定义的任务执行列表,请将--name
和
任务定义名称 - 例如task execution list --name foo
.检索完整
任务执行的详细信息,请使用task execution status
命令,任务执行的 ID,
例如task execution status --id 549
.
25.7. 销毁任务定义
销毁任务定义会从定义存储库中删除该定义。
这可以通过 RESTful API 或 shell 来完成。
要通过 shell 销毁任务,请使用task destroy
命令,如以下示例所示:
dataflow:>task destroy mytask
Destroyed task 'mytask'
这task destroy
command 还有一个选项cleanup
被销毁的任务的任务执行,如以下示例所示:
dataflow:>task destroy mytask --cleanup
Destroyed task 'mytask'
默认情况下,cleanup
选项设置为false
(也就是说,默认情况下,当任务被销毁时,不会清理任务执行)。
要通过 shell 销毁所有任务,请使用task all destroy
命令,如以下示例所示:
dataflow:>task all destroy
Really destroy all tasks? [y, n]: y
All tasks destroyed
如果需要,您可以使用力开关:
dataflow:>task all destroy --force
All tasks destroyed
先前为定义启动的任务的任务执行信息保留在任务存储库中。
这不会停止此定义当前正在运行的任何任务。相反,它会从数据库中删除任务定义。 |
+
.使用 |
25.8. 验证任务
有时,任务定义中包含的应用程序在其注册中具有无效的 URI。
这可能是由于在应用程序注册时输入了无效的 URI,或者应用程序从要从中提取它的存储库中删除了。
要验证任务中包含的所有应用程序是否可解析,请使用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:timestamp
申请有效。
现在我们可以看到,如果我们的流定义具有无效的注册应用程序会发生什么:
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 指出该任务无效,因为task:badtimestamp
具有无效的 URI。
25.9. 停止任务执行
在某些情况下,由于平台或应用程序业务逻辑本身的问题,在平台上运行的任务可能不会停止。
对于这种情况,Spring Cloud Data Flow 提供了向平台发送请求以结束任务的功能。
为此,请提交一个task execution stop
对于一组给定的任务执行,如下所示:
task execution stop --ids 5
Request to stop the task execution with id(s): 5 has been submitted
使用上述命令,触发器停止执行id=5
提交给底层部署程序实现。因此,该作将停止该任务。当我们查看任务执行的结果时,我们看到任务执行完成时退出代码为 0:
dataflow:>task execution list
╔══════════╤══╤════════════════════════════╤════════════════════════════╤═════════╗
║Task Name │ID│ Start Time │ End Time │Exit Code║
╠══════════╪══╪════════════════════════════╪════════════════════════════╪═════════╣
║batch-demo│5 │Mon Jul 15 13:58:41 EDT 2019│Mon Jul 15 13:58:55 EDT 2019│0 ║
║timestamp │1 │Mon Jul 15 09:26:41 EDT 2019│Mon Jul 15 09:26:41 EDT 2019│0 ║
╚══════════╧══╧════════════════════════════╧════════════════════════════╧═════════╝
如果为具有子任务执行关联的任务执行(例如组合任务)提交停止,则会为每个子任务执行发送停止请求。
当停止具有正在运行的 Spring Batch 作业的任务执行时,该作业的批处理状态为STARTED .
当请求停止时,每个受支持的平台都会向任务应用程序发送 SIG-INT。这允许 Spring Cloud Task 捕获应用程序的状态。但是,Spring Batch 不处理 SIG-INT,因此作业停止但保持 STARTED 状态。 |
启动远程分区 Spring Batch Task 应用程序时,Spring Cloud Data Flow 支持直接停止 Cloud Foundry 和 Kubernetes 平台的工作器分区任务。本地平台不支持停止工作器分区任务。 |
25.9.1. 停止在 Spring Cloud Data Flow 之外启动的任务执行
您可能希望停止已在 Spring Cloud Data Flow 之外启动的任务。这方面的一个示例是由远程批处理分区应用程序启动的工作程序应用程序。
在这种情况下,远程批处理分区应用程序会存储external-execution-id
对于每个工作程序应用程序。但是,不会存储任何平台信息。
因此,当 Spring Cloud Data Flow 必须停止远程批处理分区应用程序及其工作程序应用程序时,您需要指定平台名称,如下所示:
dataflow:>task execution stop --ids 1 --platform myplatform
Request to stop the task execution with id(s): 1 for platform myplatform has been submitted
26. 订阅任务和批处理事件
您还可以在任务启动时利用各种任务和批处理事件。
如果启用了任务以生成任务或批处理事件(具有spring-cloud-task-stream
并且,在卡夫卡作为活页夹的情况下,spring-cloud-stream-binder-kafka
),这些事件将在任务生命周期内发布。
默认情况下,代理上发布的事件(Rabbit、Kafka 等)的目标名称是事件名称本身(例如:task-events
,job-execution-events
,依此类推)。
dataflow:>task create myTask --definition "myBatchJob"
dataflow:>stream create task-event-subscriber1 --definition ":task-events > log" --deploy
dataflow:>task launch myTask
您可以通过在启动任务时指定显式名称来控制这些事件的目标名称,如下所示:
dataflow:>stream create task-event-subscriber2 --definition ":myTaskEvents > log" --deploy
dataflow:>task launch myTask --properties "app.myBatchJob.spring.cloud.stream.bindings.task-events.destination=myTaskEvents"
下表列出了代理上的默认任务和批处理事件和目标名称:
事件 |
目的地 |
任务事件 |
|
作业执行事件 |
|
步骤执行事件 |
|
项目读取事件 |
|
项目流程事件 |
|
项目写入事件 |
|
跳过事件 |
|
27. 组合任务
Spring Cloud Data Flow 允许您创建一个有向图,其中图的每个节点都是一个任务应用程序。 这是通过使用 DSL 进行组合任务来完成的。 您可以通过 RESTful API、Spring Cloud Data Flow Shell 或 Spring Cloud Data Flow UI 创建组合任务。
27.1. 组合任务运行器
组合任务通过称为组合任务运行器的任务应用程序运行。Spring Cloud Data Flow 服务器在启动组合任务时自动部署组合任务运行器。
27.1.1. 配置组合任务运行器
组合的任务运行器应用程序具有dataflow-server-uri
用于验证和启动子任务的属性。
默认为localhost:9393
.如果您运行分布式 Spring Cloud Data Flow 服务器,就像在 Cloud Foundry 或 Kubernetes 上部署服务器一样,您需要提供可用于访问服务器的 URI。
您可以通过设置dataflow-server-uri
属性,或者通过设置spring.cloud.dataflow.server.uri
Spring Cloud Data Flow 服务器启动时的属性。
对于后一种情况,dataflow-server-uri
组合任务运行器应用程序属性在启动组合任务时自动设置。
配置选项
这ComposedTaskRunner
task 具有以下选项:
-
composed-task-arguments
用于每个任务的命令行参数。(字符串,默认值:<none>)。 -
increment-instance-enabled
允许单个ComposedTaskRunner
实例,无需更改参数,通过添加基于run.id
从上一次执行。(布尔值,默认:true
). ComposedTaskRunner 是使用 Spring Batch 构建的。因此,成功执行后,批处理作业被视为完成。 要启动相同的ComposedTaskRunner
definition 多次,则必须将increment-instance-enabled
或uuid-instance-enabled
属性设置为true
或更改每次启动的定义参数。 使用此选项时,必须将其应用于所需应用程序的所有任务启动,包括首次启动。 -
uuid-instance-enabled
允许单个ComposedTaskRunner
实例再次运行,而无需更改参数,方法是将 UUID 添加到ctr.id
job 参数。(布尔值,默认:false
). ComposedTaskRunner 是使用 Spring Batch 构建的。因此,成功执行后,批处理作业被视为完成。 要启动相同的ComposedTaskRunner
definition 多次,则必须将increment-instance-enabled
或uuid-instance-enabled
属性设置为true
或更改每次启动的定义参数。 使用此选项时,必须将其应用于所需应用程序的所有任务启动,包括首次启动。当此选项设置为 true 时,将覆盖increment-instance-id
. 将此选项设置为true
同时运行同一组合任务定义的多个实例时。 -
interval-time-between-checks
时间量(以毫秒为单位)ComposedTaskRunner
在数据库检查之间等待,以查看任务是否已完成。(整数,默认:10000
).ComposedTaskRunner
使用数据存储来确定每个子任务的状态。此间隔表示ComposedTaskRunner
它应该多久检查一次状态,其子任务。 -
transaction-isolation-level
为组合任务运行器建立事务隔离级别。 可以在此处找到可用事务隔离级别的列表。 默认值为ISOLATION_REPEATABLE_READ
. -
max-wait-time
在执行“组合”任务失败之前,单个步骤可以运行的最长时间(以毫秒为单位)(整数,默认值:0)。 确定在点击率以失败结束之前允许每个子任务运行的最长时间。默认值0
表示没有超时。 -
split-thread-allow-core-thread-timeout
指定是否允许拆分核心线程超时。(布尔值,默认:false
) 设置策略,用于控制核心线程是否超时并终止(如果在保持活动时间内没有任务到达),并在新任务到达时根据需要进行替换。 -
split-thread-core-pool-size
Split 的核心池大小。(整数,默认:1
) 拆分中包含的每个子任务都需要一个线程才能执行。因此,例如,定义例如<AAA || BBB || CCC> && <DDD || EEE>
将需要一个split-thread-core-pool-size
之3
. 这是因为最大的拆分包含三个子任务。计数2
意味着AAA
和BBB
将并行运行,但 CCC 将等到AAA
或BBB
完成才能运行。 然后DDD
和EEE
将并行运行。 -
split-thread-keep-alive-seconds
斯普利特的线程保持活力秒。(整数,默认:60
) 如果池当前的corePoolSize
线程,如果多余线程的空闲时间超过keepAliveTime
. -
split-thread-max-pool-size
Split 的最大池大小。(整数,默认:Integer.MAX_VALUE
). 建立线程池允许的最大线程数。 -
拆分线程队列容量斯普利特的容量
BlockingQueue
.(整数,默认:Integer.MAX_VALUE
)-
如果小于
corePoolSize
线程正在运行,则Executor
总是更喜欢添加新线程而不是排队。 -
如果
corePoolSize
或更多线程正在运行,则Executor
始终更喜欢将请求排队而不是添加新线程。 -
如果请求无法排队,则创建一个新线程,除非这将超过
maximumPoolSize
.在这种情况下,任务将被拒绝。
-
-
split-thread-wait-for-tasks-to-complete-on-shutdown
是否在关机时等待定时任务完成,不中断正在运行的任务并运行队列中的所有任务。(布尔值,默认:false
) -
dataflow-server-uri
接收任务启动请求的数据流服务器的 URI。(字符串,默认:localhost:9393
) -
dataflow-server-username
接收任务启动请求的数据流服务器的可选用户名。 用于使用基本身份验证访问数据流服务器。如果出现以下情况,则不使用dataflow-server-access-token
已设置。 -
dataflow-server-password
接收任务启动请求的数据流服务器的可选密码。 用于使用基本身份验证访问数据流服务器。如果出现以下情况,则不使用dataflow-server-access-token
已设置。 -
dataflow-server-access-token
此属性设置可选的 OAuth2 访问Tokens。 通常,该值是使用当前登录用户的Tokens(如果可用)自动设置的。 但是,对于特殊用例,也可以显式设置此值。
一个特殊的布尔属性,dataflow-server-use-user-access-token
,当您想要使用当前登录用户的访问Tokens并将其传播到组合任务运行器时,则存在。使用此属性
通过 Spring Cloud Data Flow,如果设置为true
,自动填充dataflow-server-access-token
财产。使用时dataflow-server-use-user-access-token
,则必须为每个任务执行传递它。
在某些情况下,用户的dataflow-server-access-token
默认情况下,必须为每个组合任务启动传递。
在这种情况下,将 Spring Cloud 数据流spring.cloud.dataflow.task.useUserAccessToken
属性设置为true
.
若要为 Composed Task Runner 设置属性,需要在属性前加上app.composed-task-runner.
.
例如,要将dataflow-server-uri
属性将是什么样子app.composed-task-runner.dataflow-server-uri
.
27.2. 组合任务的生命周期
组合任务的生命周期分为三个部分:
27.2.1. 创建组合任务
通过task create命令创建任务定义时,使用组合任务的DSL,如以下示例所示:
dataflow:> app register --name timestamp --type task --uri maven://org.springframework.cloud.task.app:timestamp-task:
dataflow:> app register --name mytaskapp --type task --uri file:///home/tasks/mytask.jar
dataflow:> task create my-composed-task --definition "mytaskapp && timestamp"
dataflow:> task launch my-composed-task
在前面的示例中,我们假设组合任务要使用的应用程序尚未注册。
因此,在前两个步骤中,我们注册了两个任务应用程序。
然后,我们使用task create
命令。
启动前例中的组合任务 DSL 时,运行mytaskapp
,然后运行时间戳应用程序。
但在我们启动my-composed-task
定义,我们可以查看 Spring Cloud Data Flow 为我们生成的内容。
这可以通过使用任务列表命令来完成,如以下示例所示(包括其输出):
dataflow:>task list
╔══════════════════════════╤══════════════════════╤═══════════╗
║ Task Name │ Task Definition │Task Status║
╠══════════════════════════╪══════════════════════╪═══════════╣
║my-composed-task │mytaskapp && timestamp│unknown ║
║my-composed-task-mytaskapp│mytaskapp │unknown ║
║my-composed-task-timestamp│timestamp │unknown ║
╚══════════════════════════╧══════════════════════╧═══════════╝
在示例中,Spring Cloud Data Flow 创建了三个任务定义,一个用于构成我们组合任务的每个应用程序(my-composed-task-mytaskapp
和my-composed-task-timestamp
)以及组合的任务(my-composed-task
) 定义。
我们还看到,为子任务生成的每个名称都由组合任务的名称和应用程序的名称组成,用连字符分隔(如 my-composed-task mytaskapp 中)。-
-
任务应用参数
构成组合任务定义的任务应用程序也可以包含参数,如以下示例所示:
dataflow:> task create my-composed-task --definition "mytaskapp --displayMessage=hello && timestamp --format=YYYY"
27.2.2. 启动组合任务
启动组合任务的方式与启动独立任务的方式相同,如下所示:
task launch my-composed-task
启动任务后,假设所有任务都成功完成,则在运行task execution list
,如以下示例所示:
dataflow:>task execution list
╔══════════════════════════╤═══╤════════════════════════════╤════════════════════════════╤═════════╗
║ Task Name │ID │ Start Time │ End Time │Exit Code║
╠══════════════════════════╪═══╪════════════════════════════╪════════════════════════════╪═════════╣
║my-composed-task-timestamp│713│Wed Apr 12 16:43:07 EDT 2017│Wed Apr 12 16:43:07 EDT 2017│0 ║
║my-composed-task-mytaskapp│712│Wed Apr 12 16:42:57 EDT 2017│Wed Apr 12 16:42:57 EDT 2017│0 ║
║my-composed-task │711│Wed Apr 12 16:42:55 EDT 2017│Wed Apr 12 16:43:15 EDT 2017│0 ║
╚══════════════════════════╧═══╧════════════════════════════╧════════════════════════════╧═════════╝
在前面的示例中,我们看到my-compose-task
启动,其他任务也按顺序启动。
他们每个人都成功运行了Exit Code
如0
.
将属性传递给子任务
要在任务启动时在组合任务图中设置子任务的属性,
使用以下格式:app.<child task app name>.<property>
.
以下列表显示了组合任务定义作为示例:
dataflow:> task create my-composed-task --definition "mytaskapp && mytimestamp"
拥有mytaskapp
显示 'HELLO' 并将mytimestamp
timestamp 格式设置为YYYY
对于组合任务定义,请使用以下任务启动格式:
task launch my-composed-task --properties "app.mytaskapp.displayMessage=HELLO,app.mytimestamp.timestamp.format=YYYY"
与应用程序属性类似,您还可以将deployer
属性,使用以下格式:deployer.<child task app name>.<deployer-property>
:
task launch my-composed-task --properties "deployer.mytaskapp.memory=2048m,app.mytimestamp.timestamp.format=HH:mm:ss"
Launched task 'a1'
将参数传递给组合任务运行器
您可以使用--arguments
选择:
dataflow:>task create my-composed-task --definition "<aaa: timestamp || bbb: timestamp>"
Created new task 'my-composed-task'
dataflow:>task launch my-composed-task --arguments "--increment-instance-enabled=true --max-wait-time=50000 --split-thread-core-pool-size=4" --properties "app.bbb.timestamp.format=dd/MM/yyyy HH:mm:ss"
Launched task 'my-composed-task'
退出状态
以下列表显示了如何为每个步骤执行后的组合任务中包含的每个步骤(任务)设置退出状态:
-
如果
TaskExecution
有一个ExitMessage
,用作ExitStatus
. -
如果没有
ExitMessage
存在,并且ExitCode
设置为零,则ExitStatus
对于步骤是COMPLETED
. -
如果没有
ExitMessage
存在,并且ExitCode
设置为任何非零数字,则ExitStatus
对于步骤是FAILED
.
27.2.3. 销毁组合任务
用于销毁独立任务的命令与用于销毁组合任务的命令相同。
唯一的区别是,销毁组合任务也会销毁与其关联的子任务。
以下示例显示了使用destroy
命令:
dataflow:>task list
╔══════════════════════════╤══════════════════════╤═══════════╗
║ Task Name │ Task Definition │Task Status║
╠══════════════════════════╪══════════════════════╪═══════════╣
║my-composed-task │mytaskapp && timestamp│COMPLETED ║
║my-composed-task-mytaskapp│mytaskapp │COMPLETED ║
║my-composed-task-timestamp│timestamp │COMPLETED ║
╚══════════════════════════╧══════════════════════╧═══════════╝
...
dataflow:>task destroy my-composed-task
dataflow:>task list
╔═════════╤═══════════════╤═══════════╗
║Task Name│Task Definition│Task Status║
╚═════════╧═══════════════╧═══════════╝
27.2.4. 停止组合任务
如果需要停止组合任务执行,可以通过以下命令执行:
-
RESTful API
-
Spring Cloud 数据流仪表板
要通过仪表板停止组合任务,请选择作业选项卡,然后单击要停止的作业执行旁边的 *Stop() 按钮。
当当前正在运行的子任务完成时,组合任务运行将停止。与在组合任务停止时正在运行的子任务关联的步骤标记为STOPPED
以及组合任务作业执行。
27.2.5. 重新启动组合任务
组合任务在执行过程中失败,且组合任务的状态为FAILED
,则可以重新启动任务。
您可以通过以下方式执行此作:
-
RESTful API
-
外壳
-
Spring Cloud 数据流仪表板
若要通过 shell 重新启动组合任务,请使用相同的参数启动任务。 要通过仪表板重新启动组合任务,请选择“作业”选项卡,然后单击要重新启动的作业执行旁边的“重新启动”按钮。
重新启动已停止的组合任务作业(通过 Spring Cloud Data Flow Dashboard 或 RESTful API)会重新启动STOPPED 子任务,然后按指定顺序启动剩余(未启动的)子任务。 |
28. 组合任务 DSL
组合任务可以通过三种方式运行:
28.1. 条件执行
条件执行通过使用双&符号()来表示。
这样,序列中的每个任务仅在前一个任务
成功完成,如以下示例所示:&&
task create my-composed-task --definition "task1 && task2"
当组合任务调用my-composed-task
启动时,它会启动名为task1
并且,如果task1
成功完成,则名为task2
被推出。
如果task1
失败task2
不会启动。
您还可以使用 Spring Cloud Data Flow Dashboard 创建条件执行,方法是使用设计器拖放所需的应用程序并将它们连接在一起以创建有向图,如下图所示:

上图是使用 Spring Cloud Data Flow Dashboard 创建的有向图的屏幕截图。 可以看到,图中的四个组件构成条件执行:
-
开始图标:所有有向图都从此符号开始。只有一个。
-
任务图标:表示有向图中的每个任务。
-
结束图标:表示有向图的结束。
-
实线箭头:表示以下之间的流条件执行流:
-
两个应用程序。
-
启动控制节点和应用程序。
-
应用程序和终端控制节点。
-
-
结束图标:所有有向图都在此符号处结束。
您可以通过单击“定义”选项卡上组合任务定义旁边的“详细信息”按钮来查看有向图的关系图。 |
28.2. 过渡执行
DSL 支持对有向图执行期间进行的转换进行细粒度控制。
通过提供基于上一个任务的退出状态的相等条件来指定转换。
任务转换由以下符号表示。->
28.2.1. 基本转换
基本转换如下所示:
task create my-transition-composed-task --definition "foo 'FAILED' -> bar 'COMPLETED' -> baz"
在前面的示例中,foo
将启动,并且,如果它的退出状态为FAILED
这bar
任务将启动。
如果退出状态为foo
是COMPLETED
,baz
将启动。
返回的所有其他状态cat
没有效果,任务将正常结束。
使用 Spring Cloud Data Flow Dashboard 创建相同的“基本过渡”将类似于下图:

上图是在 Spring Cloud Data Flow Dashboard 中创建的有向图的屏幕截图。 请注意,有两种不同类型的连接器:
-
虚线:表示从应用程序到可能的目标应用程序之一的转换。
-
实线:以条件执行或应用程序与控制节点(开始或结束)之间的连接连接应用程序。
要创建过渡连接器,请执行以下作:
-
创建转换时,使用连接器将应用程序链接到每个可能的目标。
-
完成后,转到每个连接并通过单击选择它。
-
将出现一个螺栓图标。
-
单击该图标。
-
输入该连接器所需的退出状态。
-
该连接器的实线将变为虚线。
28.2.2. 使用通配符进行转换
DSL 支持转换使用通配符,如以下示例所示:
task create my-transition-composed-task --definition "foo 'FAILED' -> bar '*' -> baz"
在前面的示例中,foo
将启动,并且,如果它的退出状态为FAILED
,bar
任务将启动。
对于任何cat
以外FAILED
,baz
将启动。
使用 Spring Cloud Data Flow Dashboard 创建相同的“使用通配符的转换”将类似于下图:

28.2.3. 使用以下条件执行进行转换
转换后可以进行条件执行,只要通配符 不使用,如以下示例所示:
task create my-transition-conditional-execution-task --definition "foo 'FAILED' -> bar 'UNKNOWN' -> baz && qux && quux"
在前面的示例中,foo
将启动,并且,如果它的退出状态为FAILED
这bar
任务将启动。
如果foo
退出状态为UNKNOWN
,baz
将启动。
对于任何foo
以外FAILED
或UNKNOWN
,qux
将启动,并在成功完成后,quux
将启动。
使用 Spring Cloud Data Flow Dashboard 创建相同的“条件执行过渡”将类似于下图:

在此图中,虚线(过渡)连接foo 应用程序到目标应用程序,但一条实线连接了foo ,qux 和quux . |
28.2.4. 忽略退出消息
如果拆分中的任何子任务返回ExitMessage
以外COMPLETED
分裂
将有一个ExitStatus
之FAILED
.要忽略ExitMessage
子任务的,
添加ignoreExitMessage=true
对于每个将返回ExitMessage
在分裂中。使用此标志时,ExitStatus
的任务将是COMPLETED
如果ExitCode
子任务为零。拆分将有一个ExitStatus
之FAILED
如果ExitCode`s is non zero. There are 2 ways to
set the `ignoreExitMessage
旗:
-
为需要具有 exitMessage 的每个应用设置属性 在拆分中忽略。例如,像
<AAA || BBB>
哪里BBB
将返回一个exitMessage
,您可以将ignoreExitMessage
属性,如app.BBB.ignoreExitMessage=true
-
您还可以使用 composed-task-arguments 属性为所有应用程序设置它, 例如:
--composed-task-arguments=--ignoreExitMessage=true
.
28.3. 拆分执行
拆分允许并行运行组合任务中的多个任务。
它通过使用尖括号 () 对要并行运行的任务和流进行分组来表示。
这些任务和流程由双管隔开<>
||
符号,如以下示例所示:
task create my-split-task --definition "<foo || bar || baz>"
前面的示例启动任务foo
,bar
和baz
并行。
使用 Spring Cloud Data Flow Dashboard 创建相同的“拆分执行”类似于下图:

使用任务 DSL,您还可以连续运行多个拆分组,如以下示例所示:
task create my-split-task --definition "<foo || bar || baz> && <qux || quux>"
在前面的示例中,foo
,bar
和baz
任务并行启动。
一旦它们全部完成,那么qux
和quux
任务并行启动。
完成后,组合的任务结束。
但是,如果foo
,bar
或baz
fails,则包含qux
和quux
不会启动。
使用 Spring Cloud Data Flow Dashboard 创建相同的“具有多个组的拆分”将类似于下图:

请注意,有一个SYNC
设计器在以下情况下插入的控制节点
连接两个连续的分裂。
拆分中使用的任务不应设置其ExitMessage .设置ExitMessage 仅供使用
有过渡。 |
28.3.1. 包含条件执行的拆分
拆分也可以在尖括号内进行条件执行,如以下示例所示:
task create my-split-task --definition "<foo && bar || baz>"
在前面的示例中,我们看到foo
和baz
并行启动。
然而bar
直到foo
成功完成。
使用 Spring Cloud Data Flow Dashboard 创建相同的”split containing conditional execution
“ 类似于下图:

28.3.2. 为拆分建立正确的线程计数
拆分中包含的每个子任务都需要一个线程才能运行。要正确设置此设置,您需要查看图表并找到具有最多子任务数量的拆分。该拆分中的子任务数就是您需要的线程数。
要设置线程计数,请使用split-thread-core-pool-size property
(默认为1
).因此,例如,定义例如<AAA || BBB || CCC> && <DDD || EEE>
需要一个split-thread-core-pool-size
之3
.
这是因为最大的拆分包含三个子任务。数到 2 意味着AAA
和BBB
将并行运行,但 CCC 将等待AAA
或BBB
为了运行而完成。
然后DDD
和EEE
将并行运行。
29. 从流启动任务
您可以使用task-launcher-dataflow
sink,作为 Spring Cloud Data Flow 项目的一部分提供。
接收器连接到数据流服务器,并使用其 REST API 启动任何定义的任务。
接收器接受表示task launch request
,它提供要启动的任务的名称,并且可能包括命令行参数和部署属性。
这task-launch-request-function
组件与 Spring Cloud Stream 函数组合相结合,可以将任何源或处理器的输出转换为任务启动请求。
将依赖项添加到task-launch-request-function
自动配置一个java.util.function.Function
实现,通过 Spring Cloud 函数注册为taskLaunchRequest
.
例如,您可以从时间源开始,添加以下依赖项,构建它,并将其注册为自定义源。
<dependency>
<groupId>org.springframework.cloud.stream.app</groupId>
<artifactId>app-starters-task-launch-request-common</artifactId>
</dependency>
要构建应用程序,请按照此处的说明进行作。
这将创建一个apps
包含time-source-rabbit
和time-source-kafka
目录中的<stream app project>/applications/source/time-source
目录。在每个目录中,您都会看到一个目标目录,其中包含一个time-source-<binder>-<version>.jar
.现在注册time-source
jar(使用适当的活页夹 jar),并将 SCDF 作为名为timestamp-tlr
.
接下来,注册task-launcher-dataflow
使用 SCDF 进行接收并创建任务定义timestamp-task
.完成此作后,创建流定义,如下所示:
stream create --name task-every-minute --definition 'timestamp-tlr --fixed-delay=60000 --task.launch.request.task-name=timestamp-task --spring.cloud.function.definition=\"timeSupplier|taskLaunchRequestFunction\"| tasklauncher-sink' --deploy
前面的流每分钟生成一个任务启动请求。该请求提供要启动的任务的名称:{"name":"timestamp-task"}
.
以定义说明了命令行参数的用法。它生成消息,例如{"args":["foo=bar","time=12/03/18 17:44:12"],"deploymentProps":{},"name":"timestamp-task"}
要为任务提供命令行参数,请执行以下作:
stream create --name task-every-second --definition 'timestamp-tlr --task.launch.request.task-name=timestamp-task --spring.cloud.function.definition=\"timeSupplier|taskLaunchRequestFunction\" --task.launch.request.args=foo=bar --task.launch.request.arg-expressions=time=payload | tasklauncher-sink' --deploy
请注意,使用 SpEL 表达式将每个消息有效负载映射到time
命令行参数,以及静态参数 (foo=bar
).
然后,您可以使用 shell 命令查看任务执行列表task execution list
,如以下示例所示(及其输出):
dataflow:>task execution list
╔══════════════╤═══╤════════════════════════════╤════════════════════════════╤═════════╗
║ Task Name │ID │ Start Time │ End Time │Exit Code║
╠══════════════╪═══╪════════════════════════════╪════════════════════════════╪═════════╣
║timestamp-task│581│Thu Sep 08 11:38:33 EDT 2022│Thu Sep 08 11:38:33 EDT 2022│0 ║
║timestamp-task│580│Thu Sep 08 11:38:31 EDT 2022│Thu Sep 08 11:38:31 EDT 2022│0 ║
║timestamp-task│579│Thu Sep 08 11:38:29 EDT 2022│Thu Sep 08 11:38:29 EDT 2022│0 ║
║timestamp-task│578│Thu Sep 08 11:38:26 EDT 2022│Thu Sep 08 11:38:26 EDT 2022│0 ║
╚══════════════╧═══╧════════════════════════════╧════════════════════════════╧═════════╝
在此示例中,我们展示了如何使用time
source 以固定速率启动任务。
此模式可以应用于任何源,以启动任务以响应任何事件。
29.1. 从流启动组合任务
可以使用task-launcher-dataflow
sink,如此处所讨论的。
由于我们使用ComposedTaskRunner
直接,我们需要在创建组合任务启动流之前,为组合任务运行器本身以及组合任务设置任务定义。
假设我们想要创建以下组合任务定义:AAA && BBB
.
第一步是创建任务定义,如以下示例所示:
task create --name composed-task-sample --definition "AAA: timestamp && BBB: timestamp"
现在,组合任务定义所需的任务定义已准备就绪,我们需要创建一个启动composed-task-sample
.
我们创建一个流:
-
这
timestamp-tlr
源自定义以发出任务启动请求,如前所示。 -
这
task-launcher
sink 启动composed-task-sample
流应类似于以下内容:
stream create --name ctr-stream --definition "timestamp-tlr --fixed-delay=30000 --spring.cloud.function.definition=\"timeSupplier|taskLaunchRequestFunction\" --task.launch.request.task-name=composed-task-sample | tasklauncher-sink" --deploy
30. 与任务共享 Spring Cloud Data Flow 的数据存储
正如 Tasks 文档中所讨论的,Spring Cloud Data Flow 允许您查看 Spring Cloud Task 应用程序执行情况。所以,在 本节,我们将讨论任务应用程序和 Spring 所需的内容 云数据流,共享任务执行信息。
30.1. 常见的 DataStore 依赖项
Spring Cloud Data Flow 支持许多开箱即用的数据库,
因此,您通常需要做的就是声明spring_datasource_*
环境变量
以建立 Spring Cloud Data Flow 需要的数据存储。
无论您决定将哪个数据库用于 Spring Cloud Data Flow,请确保您的任务还
在其pom.xml
或gradle.build
文件。如果数据库依赖项
Spring Cloud Data Flow 使用的任务应用程序中不存在,则任务失败
并且不会记录任务执行。
30.2. 通用数据存储
Spring Cloud Data Flow 和您的任务应用程序必须访问同一个数据存储实例。 这样,Spring Cloud Data Flow 可以读取任务应用程序记录的任务执行,以将它们列在 Shell 和 Dashboard 视图中。 此外,任务应用程序必须具有对 Spring Cloud Data Flow 使用的任务数据表的读写权限。
鉴于对 Task 应用程序和 Spring Cloud Data Flow 之间的数据源依赖关系的理解,您现在可以查看如何在各种 Task 编排场景中应用它们。
30.2.1. 简单任务启动
从 Spring Cloud Data Flow 启动任务时,Data Flow 会添加其数据源
属性 (spring.datasource.url
,spring.datasource.driverClassName
,spring.datasource.username
,spring.datasource.password
)
到正在启动的任务的应用程序属性。因此,任务应用程序
将其任务执行信息记录到 Spring Cloud Data Flow 存储库中。
30.2.2. 组合任务运行器
31. 调度任务
Spring Cloud Data Flow 允许您使用cron
表达。
您可以通过 RESTful API 或 Spring Cloud Data Flow UI 创建计划。
31.1. 调度器
Spring Cloud Data Flow 通过云平台上可用的调度代理来调度其任务的执行。 使用 Cloud Foundry 平台时,Spring Cloud Data Flow 使用 PCF 调度器。 使用 Kubernetes 时,将使用 CronJob。
计划任务不实现持续部署功能。对 Spring Cloud Data Flow 中任务定义的应用程序版本或属性的任何更改都不会影响计划任务。 |

31.2. 启用调度
默认情况下,Spring Cloud Data Flow 禁用调度功能。若要启用计划功能,请将以下功能属性设置为true
:
-
spring.cloud.dataflow.features.schedules-enabled
-
spring.cloud.dataflow.features.tasks-enabled
31.3. 计划的生命周期
计划的生命周期分为三个部分:
31.3.1. 安排任务执行
您可以通过以下方式计划任务执行:
-
Spring Cloud 数据流 Shell
-
Spring Cloud 数据流仪表板
-
Spring Cloud 数据流 RESTful API
31.3.2. 安排任务
要使用 shell 计划任务,请使用task schedule create
命令创建计划,如以下示例所示:
dataflow:>task schedule create --definitionName mytask --name mytaskschedule --expression '*/1 * * * *'
Created schedule 'mytaskschedule'
在前面的示例中,我们创建了一个名为mytaskschedule
对于名为mytask
. 此计划启动mytask
每分钟一次。
如果使用 Cloud Foundry,则cron 上面的表达式将是:*/1 * ? * * . 这是因为 Cloud Foundry 使用 Quartzcron 表达式格式。 |
计划名称的最大长度
计划名称的最大字符长度取决于平台。
Kubernetes | 云代工厂 | 当地 |
---|---|---|
52 |
63 |
不适用 |
31.3.3. 删除计划
您可以使用以下命令删除计划:
-
Spring Cloud 数据流 Shell
-
Spring Cloud 数据流仪表板
-
Spring Cloud 数据流 RESTful API
要使用 shell 删除任务计划,请使用task schedule destroy
命令,如以下示例所示:
dataflow:>task schedule destroy --name mytaskschedule
Deleted task schedule 'mytaskschedule'
31.3.4. 上市时间表
您可以使用以下命令查看可用的计划:
-
Spring Cloud 数据流 Shell
-
Spring Cloud 数据流仪表板
-
Spring Cloud 数据流 RESTful API
要从 shell 查看您的计划,请使用task schedule list
命令,如以下示例所示:
dataflow:>task schedule list
╔══════════════════════════╤════════════════════╤════════════════════════════════════════════════════╗
║ Schedule Name │Task Definition Name│ Properties ║
╠══════════════════════════╪════════════════════╪════════════════════════════════════════════════════╣
║mytaskschedule │mytask │spring.cloud.scheduler.cron.expression = */1 * * * *║
╚══════════════════════════╧════════════════════╧════════════════════════════════════════════════════╝
可以使用 Spring Cloud Data Flow UI 创建、删除和列出计划的说明,请参见此处。 |
32. 持续部署
随着任务应用程序的发展,您希望将更新引入生产环境。本节介绍了 Spring Cloud Data Flow 围绕更新任务应用程序提供的功能。
注册任务应用程序时(请参阅注册任务应用程序),将有一个版本与其相关联。任务应用程序可以有多个版本与其关联,其中一个版本作为默认值。下图演示了具有多个版本关联的应用程序(请参阅时间戳条目)。

应用程序的版本通过注册具有相同名称和坐标的多个应用程序(版本除外)来管理。例如,如果要使用以下值注册一个应用程序,则将获得使用两个版本(2.1.0.RELEASE 和 2.1.1.RELEASE)注册的应用程序:
-
应用1
-
名字:
timestamp
-
类型:
task
-
URI:
maven://org.springframework.cloud.task.app:timestamp-task:2.1.0.RELEASE
-
-
应用2
-
名字:
timestamp
-
类型:
task
-
URI:
maven://org.springframework.cloud.task.app:timestamp-task:2.1.1.RELEASE
-
除了有多个版本之外,Spring Cloud Data Flow 还需要知道在下次启动时要运行哪个版本。这可以通过将版本设置为默认版本来指示。无论任务应用程序的哪个版本被配置为默认版本,都是在下一个启动请求时运行的版本。您可以在 UI 中看到哪个版本是默认版本,如下图所示:

32.1. 任务启动生命周期
在以前版本的 Spring Cloud Data Flow 中,当收到启动任务的请求时,Spring Cloud Data Flow 将部署应用程序(如果需要)并运行它。如果应用程序在不需要每次都部署应用程序的平台上运行(例如CloudFoundry),则使用之前部署的应用程序。此流程在 2.3 中发生了变化。下图显示了现在收到任务启动请求时会发生什么情况:

上图中需要考虑三个主要流。第一次启动或不进行任何更改即可启动。另外两个在发生更改但应用程序当前未启动时启动,并在发生更改且应用程序正在运行时启动。我们首先查看没有变化的流程。
32.1.1. 启动没有更改的任务
-
启动请求进入数据流。数据流确定不需要升级,因为没有任何更改(自上次执行以来没有更改任何属性、部署属性或版本)。
-
在缓存已部署工件的平台(CloudFoundry,在撰写本文时),数据流会检查应用程序之前是否已部署。
-
如果需要部署应用程序,数据流将部署任务应用程序。
-
数据流将启动应用程序。
此流是默认行为,如果没有任何更改,则每次收到请求时都会发生。请注意,这与数据流始终用于启动任务的流相同。
32.1.2. 启动具有当前未运行的更改的任务
启动任务时要考虑的第二个流是任务未运行,但任何任务应用程序版本、应用程序属性或部署属性发生更改。在这种情况下,将执行以:
-
启动请求进入数据流。数据流确定需要升级,因为任务应用程序版本、应用程序属性或部署属性发生了更改。
-
数据流检查任务定义的另一个实例当前是否正在运行。
-
如果当前没有任务定义的其他实例正在运行,则删除旧部署。
-
在缓存已部署工件的平台(CloudFoundry,在撰写本文时),数据流会检查应用程序之前是否已部署(此检查的计算结果为
false
在此流中,因为旧部署已删除)。 -
数据流使用更新的值(新应用程序版本、新合并属性和新合并部署属性)部署任务应用程序。
-
数据流将启动应用程序。
此流从根本上支持Spring Cloud Data Flow的持续部署。
32.1.3. 在另一个实例运行时启动带有更改的任务
最后一个主要流程是当启动请求来到 Spring Cloud Data Flow 进行升级但任务定义当前正在运行时。在这种情况下,由于需要删除当前应用程序,启动被阻止。在某些平台(CloudFoundry,在撰写本文时),删除应用程序会导致所有当前正在运行的应用程序被关闭。此功能可防止这种情况发生。以下过程描述了当另一个实例运行时任务发生更改时会发生什么:
-
启动请求进入数据流。数据流确定需要升级,因为任务应用程序版本、应用程序属性或部署属性发生了更改。
-
数据流检查任务定义的另一个实例当前是否正在运行。
-
数据流会阻止启动,因为任务定义的其他实例正在运行。
由于需要删除任何当前正在运行的任务,因此需要升级在请求时正在运行的任务定义的任何启动都会被阻止运行。 |