此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 spring-cloud-task 3.3.0! |
特征
本节将详细介绍 Spring Cloud Task,包括如何使用它、如何配置它以及适当的扩展点。
Spring Cloud 任务的生命周期
在大多数情况下,现代云环境是围绕流程的执行而设计的预计不会结束的。如果它们确实结束,它们通常会重新启动。虽然大多数平台确实有某种方法来运行在结束时不会重新启动的进程,但该运行的该运行的结果通常不会以消耗的方式维护。春云Task 提供了在环境中执行短期进程并记录 结果。 这样做允许围绕短期进程的微服务架构以及通过消息集成任务来延长运行时间的服务。
虽然此功能在云环境中很有用,但在云环境中也可能出现同样的问题传统的部署模型也是如此。当使用调度程序(例如 cron)运行 Spring Boot 应用程序时,能够监控结果会很有用应用程序完成后。
Spring Cloud Task 采用的方法是,Spring Boot 应用程序可以有一个开始和一个结束,并且仍然成功。批处理应用程序是如何预期结束(并且通常是短暂的)的进程如何有所帮助的一个例子。
Spring Cloud Task 记录给定任务的生命周期事件。大多数长时间运行的进程(以大多数 Web 应用程序为代表)不会保存其生命周期事件。 这 Spring Cloud Task 的核心任务可以做到。
生命周期由单个任务执行组成。这是配置为任务的Spring Boot 应用程序的物理执行(即,它具有 Sprint Cloud 任务依赖项)。
在任务开始时,在任何CommandLineRunner
或ApplicationRunner
实现已运行,则TaskRepository
记录开始事件。此事件通过SmartLifecycle#start
被触发由 Spring 框架触发。这向系统表明所有 bean 都已准备好使用,并且在运行任何CommandLineRunner
或ApplicationRunner
实现 由 Spring Boot 提供。
任务的记录仅在成功引导ApplicationContext . 如果上下文根本无法引导,则任务的运行不会 记录。 |
完成所有*Runner#run
来自 Spring Boot 的调用或ApplicationContext
(由ApplicationFailedEvent
),任务执行为在存储库中更新结果。
如果应用程序需要ApplicationContext 在完成任务(全部*Runner#run 方法已被调用,并且任务repository 已更新),请将属性spring.cloud.task.closecontextEnabled 设置为 true。 |
任务执行
存储在TaskRepository
在TaskExecution
class 和由以下信息组成:
田 | 描述 |
---|---|
|
任务运行的唯一 ID。 |
|
从 |
|
任务的名称,由配置的 |
|
任务启动的时间,如 |
|
任务完成的时间,如 |
|
退出时可用的任何信息。这可以通过编程方式设置 |
|
如果异常是任务结束的原因(如 |
|
一个 |
映射退出代码
任务完成后,它会尝试将退出代码返回给作系统。如果我们看一看 在我们最初的例子中,我们可以看到我们是 不控制我们应用程序的这方面。因此,如果抛出异常,JVM 返回一个代码,该代码可能对调试有任何用处,也可能没有用处。
因此,Spring Boot 提供了一个接口,ExitCodeExceptionMapper
,这可以让您
将未捕获的异常映射到退出代码。这样做可以让您在退出级别指示
代码,出了什么问题。此外,通过以这种方式映射退出代码,Spring Cloud Task
记录返回的退出代码。
如果任务以 SIG-INT 或 SIG-TERM 终止,则退出代码为零,除非 否则在代码中指定。
当任务运行时,退出代码将作为空存储在存储库中。 任务完成后,将根据所述指南存储适当的退出代码 在本节前面。 |
配置
Spring Cloud Task 提供了一个即用型配置,如DefaultTaskConfigurer
和SimpleTaskConfiguration
类。本节将介绍
默认值以及如何根据您的需要自定义 Spring Cloud Task。
数据源
Spring Cloud Task 使用数据源来存储任务执行的结果。由
默认情况下,我们提供了一个 H2 的内存实例来提供一个简单的方法
引导开发。但是,在生产环境中,您可能希望
配置您自己的DataSource
.
如果您的应用程序仅使用单个DataSource
这既是您的业务
schema 和任务存储库,您需要做的就是提供任何DataSource
(这
最简单的方法是通过 Spring Boot 的配置约定)。这DataSource
被 Spring Cloud Task 自动用于存储库。
如果您的应用程序使用多个DataSource
,您需要配置任务
存储库,其中包含适当的DataSource
.这种自定义可以通过
实现TaskConfigurer
.
表前缀
一个可修改的属性TaskRepository
是任务表的表前缀。由
默认,它们都以TASK_
.TASK_EXECUTION
和TASK_EXECUTION_PARAMS
是两个例子。但是,修改此前缀有潜在的原因。如果
schema name 需要附加到表名称前面,或者如果多组任务
tables 需要,则必须更改表前缀。你可以这样做
通过将spring.cloud.task.tablePrefix
到您需要的前缀,如下所示:
spring.cloud.task.tablePrefix=yourPrefix
通过使用spring.cloud.task.tablePrefix
,用户承担责任
创建满足任务表架构条件但
对用户的业务需求进行修改。
在创建自己的任务 DDL 时,您可以利用 Spring Cloud 任务模式 DDL 作为指南,如此处所示。
启用/禁用表初始化
如果您正在创建任务表并且不希望 Spring Cloud Task
在任务启动时创建它们,将spring.cloud.task.initialize-enabled
属性设置为false
如下:
spring.cloud.task.initialize-enabled=false
它默认为true
.
该物业spring.cloud.task.initialize.enable 已被弃用。 |
外部生成的任务 ID
在某些情况下,您可能希望允许任务之间的时间差
请求以及基础设施实际启动它的时间。Spring Cloud Task 允许您
创建一个TaskExecution
请求任务时。然后将
生成TaskExecution
添加到任务,以便它可以更新TaskExecution
通过 任务的生命周期。
一个TaskExecution
可以通过调用createTaskExecution
方法实现TaskRepository
引用包含 这TaskExecution
对象。
为了将任务配置为使用生成的TaskExecutionId
,添加以下属性:
spring.cloud.task.executionid=yourtaskId
外部任务 ID
Spring Cloud Task 允许您为每个TaskExecution
. 为了将任务配置为使用生成的TaskExecutionId
,添加以下属性:
spring.cloud.task.external-execution-id=<externalTaskId>
父任务 ID
Spring Cloud Task 允许您为每个TaskExecution
. 示例这将是一个执行另一个或多个任务的任务,并且您想要记录哪个任务启动了每个子任务。为了将您的任务配置为设置父级TaskExecutionId
在子任务上添加以下属性:
spring.cloud.task.parent-execution-id=<parentExecutionTaskId>
任务配置器
这TaskConfigurer
是一个策略接口,可让您自定义Spring Cloud Task 的组件配置方式。默认情况下,我们提供了DefaultTaskConfigurer
那 提供逻辑默认值:Map
-基于内存中的组件(如果没有,则对开发有用DataSource
)和基于 JDBC 的组件(如果有DataSource
可用)。
这TaskConfigurer
允许您配置三个主要组件:
元件 | 描述 | 默认值(由DefaultTaskConfigurer ) |
---|---|---|
|
的实现 |
|
|
的实现 |
|
|
运行任务更新时要使用的事务管理器。 |
|
您可以通过创建
自定义实现TaskConfigurer
接口。通常,将DefaultTaskConfigurer
(如果TaskConfigurer
未找到)和
覆盖所需的 getter 就足够了。但是,从头开始实现自己的
可能需要。
用户不应直接使用TaskConfigurer 径直
除非他们使用它来提供要作为 Spring Beans 公开的实现。 |
任务执行侦听器
TaskExecutionListener
允许您为期间发生的特定事件注册侦听器
任务生命周期。为此,请创建一个实现TaskExecutionListener
接口。实现TaskExecutionListener
接口会收到以下事件的通知:
-
onTaskStartup
:在存储之前TaskExecution
进入TaskRepository
. -
onTaskEnd
:在更新TaskExecution
在TaskRepository
和 标记任务的最终状态。 -
onTaskFailed
:在onTaskEnd
当未处理的 异常。
Spring Cloud Task 还允许您将TaskExecution
bean 中方法的侦听器
通过使用以下方法注释:
-
@BeforeTask
:在存储之前TaskExecution
进入TaskRepository
-
@AfterTask
:在更新TaskExecution
在TaskRepository
标记任务的最终状态。 -
@FailedTask
:在@AfterTask
当未处理的 异常。
以下示例显示了正在使用的三个注释:
public class MyBean {
@BeforeTask
public void methodA(TaskExecution taskExecution) {
}
@AfterTask
public void methodB(TaskExecution taskExecution) {
}
@FailedTask
public void methodC(TaskExecution taskExecution, Throwable throwable) {
}
}
插入ApplicationListener 链中早于TaskLifecycleListener 存在可能会造成意想不到的效果。 |
任务执行侦听器引发的异常
如果异常是由TaskExecutionListener
事件处理程序、所有侦听器
该事件处理程序的处理停止。例如,如果三个onTaskStartup
听众
已开始,第一个onTaskStartup
事件处理程序抛出异常,另一个
二onTaskStartup
方法。但是,其他事件处理程序 (onTaskEnd
和onTaskFailed
) 的TaskExecutionListeners
被调用。
由TaskExecutionListener
事件处理程序是 ExitCodeEvent 报告的退出代码。
如果没有ExitCodeEvent
发出时,将评估抛出的异常以查看
如果它是 ExitCodeGenerator 类型。
如果是这样,它会从ExitCodeGenerator
.否则1
被返回。
如果在onTaskStartup
方法,应用程序的退出代码将为1
.
如果在任一onTaskEnd
或onTaskFailed
方法时,应用程序的退出代码将是使用上面列举的规则建立的退出代码。
如果在onTaskStartup ,onTaskEnd 或onTaskFailed 您无法使用ExitCodeExceptionMapper . |
退出消息
您可以使用TaskExecutionListener
.这是通过设置TaskExecution’s
exitMessage
,
然后将其传递给TaskExecutionListener
.以下示例显示
用@AfterTask
ExecutionListener
:
@AfterTask
public void afterMe(TaskExecution taskExecution) {
taskExecution.setExitMessage("AFTER EXIT MESSAGE");
}
一ExitMessage
可以在任何侦听器事件(onTaskStartup
,onTaskFailed
和onTaskEnd
).三个侦听器的优先级如下:
-
onTaskEnd
-
onTaskFailed
-
onTaskStartup
例如,如果您将exitMessage
对于onTaskStartup
和onTaskFailed
listeners 的 Listeners,任务结束时不会失败,exitMessage
从onTaskStartup
存储在存储库中。否则,如果发生故障,则exitMessage
从
这onTaskFailed
被存储。此外,如果您将exitMessage
使用onTaskEnd
listener,则exitMessage
从onTaskEnd
取代
来自onTaskStartup
和onTaskFailed
.
限制 Spring Cloud 任务实例
Spring Cloud Task 允许您建立只能运行一个具有给定任务名称的任务
一次。为此,您需要建立任务名称并将spring.cloud.task.single-instance-enabled=true
对于每个任务执行。虽然第一个
任务执行正在运行,则您尝试运行具有相同任务名称和spring.cloud.task.single-instance-enabled=true
这
任务失败,并显示以下错误消息:Task with name "application" is already
running.
的默认值spring.cloud.task.single-instance-enabled
是false
.这
以下示例演示如何设置spring.cloud.task.single-instance-enabled
自true
:
spring.cloud.task.single-instance-enabled=true or false
要使用此功能,您必须将以下 Spring Integration 依赖项添加到 应用:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
</dependency>
如果任务失败,应用程序的退出代码将为 1,因为此功能 已启用,并且另一个任务正在运行具有相同任务名称。 |
Spring AOT 和本机编译的单实例使用
要在创建本机编译的应用程序时使用 Spring Cloud Task 的单实例功能,您需要在构建时启用该功能。
为此,请添加 process-aot 执行并将spring.cloud.task.single-step-instance-enabled=true
作为 JVM 参数,如下所示:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
<configuration>
<jvmArguments>
-Dspring.cloud.task.single-instance-enabled=true
</jvmArguments>
</configuration>
</execution>
</executions>
</plugin>
为 ApplicationRunner 和 CommandLineRunner 启用观察
启用任务观察ApplicationRunner
或CommandLineRunner
设置spring.cloud.task.observation.enabled
设置为 true。
具有观察的示例任务应用程序允许使用SimpleMeterRegistry
可以在这里找到。
禁用 Spring Cloud 任务自动配置
如果不应为实现自动配置 Spring Cloud Task,您可以禁用 Task 的自动配置。 这可以通过向任务应用程序添加以下注释来完成:
@EnableAutoConfiguration(exclude={SimpleTaskAutoConfiguration.class})
您还可以通过设置spring.cloud.task.autoconfiguration.enabled
属性设置为false
.
关闭上下文
如果应用程序需要ApplicationContext
在完成任务(全部*Runner#run
方法已被调用,并且任务repository 已更新),请将属性spring.cloud.task.closecontextEnabled
自true
.
关闭上下文的另一种情况是任务执行完成,但应用程序不会终止。
在这些情况下,上下文保持打开状态,因为已分配线程
(例如:如果您使用的是 TaskExecutor)。在这些情况下
将spring.cloud.task.closecontextEnabled
属性设置为true
启动任务时。
这将在任务完成后关闭应用程序的上下文。
从而允许应用程序终止。
启用任务指标
Spring Cloud Task 与 Micrometer 集成,并为其执行的任务创建观察结果。
要启用任务可观测性集成,您必须将spring-boot-starter-actuator
、首选注册表实现(如果要发布指标)和 micrometer-trace(如果要发布跟踪数据)到任务应用程序。
使用 Influx 启用任务可观测性和指标的 Maven 依赖项集示例如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
<scope>runtime</scope>
</dependency>