|
对于最新的稳定版本,请使用 spring-cloud-task 3.3.0! |
特征
本节将详细介绍 Spring Cloud Task,包括如何使用它、如何使用 以配置它,以及适当的扩展点。
Spring Cloud 任务的生命周期
在大多数情况下,现代云环境是围绕流程的执行而设计的 预计不会结束。如果它们确实结束,通常会重新启动。虽然大多数 平台确实有某种方式来运行一个进程,该进程在结束时不会重新启动,因此 该运行的结果通常不会以消耗的方式进行维护。Spring Cloud Task 提供了在环境中执行短期进程并记录 结果。这样做允许围绕短期进程的微服务架构,如 以及通过消息集成任务来延长运行时间的服务。
虽然此功能在云环境中很有用,但在 传统的部署模型也是如此。当使用 调度程序,例如 cron,能够监控 完成后申请。
Spring Cloud Task 采用 Spring Boot 应用程序可以启动和 结束,仍然成功。批处理应用程序是如何处理 预计会结束(而且通常是短暂的)可能会有所帮助。
Spring Cloud Task 记录给定任务的生命周期事件。运行时间最长 以大多数 Web 应用程序为代表的进程不会保存其生命周期事件。这 Spring Cloud Task 的核心任务可以做到。
生命周期由单个任务执行组成。这是对 Spring Boot 应用程序配置为任务(即,它具有 Sprint Cloud 任务依赖项)。
在任务开始时,在任何CommandLineRunner或ApplicationRunner实现已运行,则TaskRepository记录开始
事件。此事件通过SmartLifecycle#start被触发
由 Spring Framework 提供。这向系统指示所有 bean 都已准备好使用,并且
在运行任何CommandLineRunner或ApplicationRunner实现
由 Spring Boot 提供。
任务的记录仅在成功引导ApplicationContext.如果上下文根本无法引导,则任务的运行不会
记录。 |
完成所有*Runner#run来自 Spring Boot 的调用或ApplicationContext(由ApplicationFailedEvent),任务执行为
在存储库中更新了结果。
如果应用程序需要ApplicationContext在
完成任务(所有*Runner#run方法已被调用,并且任务
存储库已更新),请将属性spring.cloud.task.closecontextEnabled设置为 true。 |
任务执行
存储在TaskRepository在TaskExecutionclass 和
由以下信息组成:
| 田 | 描述 |
|---|---|
|
任务运行的唯一 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 还允许您将TaskExecutionbean 中方法的侦听器
通过使用以下方法注释:
-
@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和onTaskFailedlisteners 的 Listeners,任务结束时不会失败,exitMessage从onTaskStartup存储在存储库中。否则,如果发生故障,则exitMessage从
这onTaskFailed被存储。此外,如果您将exitMessage使用onTaskEndlistener,则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方法已被调用,并且任务
存储库已更新),请将属性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>