Introducción
Contenido
Los microservicios se están desarrollando a nuestro alrededor hoy en día. Muchos de estos servicios son de corta duración. Las tareas programadas, la sincronización de datos, la agregación de datos, la generación de informes y servicios similares son de corta duración. Por lo general, se espera que comiencen, se ejecuten hasta su finalización y finalicen.
Se han creado muchas aplicaciones y programadores externos para cumplir con este propósito; sin embargo, a veces necesita una tarea personalizada que requiere una integración profunda con la aplicación de su organización.
La plataforma Spring Boot pone esta funcionalidad a disposición de los desarrolladores a través de Spring Cloud Task API.
¿Qué es Spring Cloud Task?
Normalmente, se espera que los servicios sean de larga duración. Un servicio Spring Boot promedio incluye un servidor web integrado como Tomcat, Jetty o Undertow. Un servicio finaliza porque se detiene a propósito o por un error de tiempo de ejecución como un OOM (OutOfMemoryError
) ocurrió.
Spring Boot se creó de esta manera, pero a medida que los paradigmas cambiaron y la arquitectura de microservicios se hizo popular, muchos servicios se volvieron efímeros. Esto fue excesivo ya que un servicio de notificación de corta duración no necesita tener un servidor integrado y podría ser mucho más liviano.
Tarea de Spring Cloud es la respuesta de Spring al problema de los microservicios de corta duración en Spring Boot.
Con Spring Cloud Task, obtiene un proceso JVM bajo demanda que realiza una tarea y finaliza de inmediato.
En este artículo, enlazaremos mucho con el proyecto oficial Spring Cloud Task disponible en Github.
Arquitectura técnica de Spring Cloud Task
Spring Cloud Task usa algunas anotaciones para configurar el sistema y una base de datos (al menos para producción) para registrar el resultado de cada invocación.
Para que su aplicación Spring Boot sea una tarea en la nube, debe anotar una de las clases de configuración de su aplicación con @EnableTask
.
Esta anotación importa el TaskLifecycleConfiguration en su proyecto. los TaskLifecycleConfiguration
class es la clase de configuración para el TaskLifecycleListener
, TaskRepository
y otras clases útiles necesarias para dar vida a todas las funcionalidades de Spring Cloud Task.
Implementación
Spring Initializr
Una buena manera de arrancar su proyecto esqueleto Spring Boot es usar Spring Initializr. Seleccione su dependencia de base de datos preferida, la dependencia de Spring Cloud Task y la dependencia de Spring Data JPA:
Si ya tiene un proyecto en ejecución, con Maven, agregue las dependencias adecuadas:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-task</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${version}</version>
</dependency>
los spring-cloud-starter-task
la dependencia incluye spring-boot-starter
, spring-cloud-task-core
, spring-cloud-task-batch
y spring-cloud-task-stream
.
los spring-cloud-task-core
la dependencia es la principal que usaremos; puede importar el spring-boot-starter
y la antigua dependencia por separado.
Alternativamente, si está usando Gradle:
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-task', version: '2.2.3.RELEASE'
Configurar la aplicación
Para registrar una aplicación como Spring Cloud Task, debe anotar una de las clases de configuración con @EnableTask
:
@EnableTask
@SpringBootApplication
public class SampleSpringCloudTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SampleSpringCloudTaskApplication.class, args);
}
}
Desde el @SpringBootApplication
la anotación es una combinación de @EnableAutoConfiguration
, @Configuration
y @ComponentScan
, está perfectamente bien anotar la clase principal con el @EnableTask
anotación.
TaskRepository
Se puede crear una tarea sin una base de datos. En ese caso, utiliza una instancia en memoria de H2 para administrar los eventos del repositorio de tareas. Esto está bien para el desarrollo, pero no para la producción. Para producción, se recomienda una fuente de datos. Conserva todos los registros de sus ejecuciones de tareas y errores.
Todos los eventos de tareas se conservan mediante el TaskRepository
.
En un proyecto de fuente de datos única, Spring Cloud Task crea las tablas de tareas en la base de datos especificada.
Sin embargo, en un proyecto de múltiples fuentes de datos, debe elegir la fuente de datos para usar con Spring Cloud Task. Puede encontrar un ejemplo de un proyecto de múltiples fuentes de datos en el Proyectos de muestra de Spring Cloud Task.
En el ejemplo, se especifican 2 fuentes de datos en el DataSoureConfiguration
clase:
@Configuration
public class DataSourceConfiguration {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
@Bean
public DataSource secondDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
}
Para especificar la fuente de datos que utilizará Spring Cloud Task, un CustomTaskConfigurer
se crea el componente. Eso extends DefaultTaskConfigurer
, pasando la fuente de datos calificada en el constructor:
@Component
public class CustomTaskConfigurer extends DefaultTaskConfigurer {
@Autowired
public CustomTaskConfigurer(@Qualifier("secondDataSource") DataSource dataSource) {
super(dataSource);
}
}
A menos que sea una costumbre TaskRepository
se especifica extendiendo el SimpleTaskRepository
, la SimpleTaskRepository
es el predeterminado TaskRepository
utilizado por Spring Cloud Task.
TaskConfigurer
los TaskConfigurer
se utiliza para personalizar las configuraciones de Spring Cloud Task. DefaultTaskConfigurer
es el configurador predeterminado que se utiliza si no hay un configurador de tareas personalizado que implemente el TaskConfigurer
se proporciona la interfaz.
DefaultTaskConfigurer
proporciona componentes basados en mapas si no hay una fuente de datos disponible y componentes JDBC si se proporciona una fuente de datos.
TaskExplorer
los TaskExplorer
, como su nombre indica, es un explorador de ejecuciones de tareas. Es útil para recopilar información real de tareas del repositorio de tareas.
De forma predeterminada, Spring Cloud Tasks usa el SimpleTaskExplorer
.
Desde el TaskExplorer
, puede consultar mucha información útil sobre las ejecuciones de tareas, como el recuento total de TaskExecutions
, actualmente en ejecución TaskExecutions
, encontrando todo TaskExecutions
etc.
Tarea Ejecución
TaskExecution
es el estado de la tarea para cada ejecución. Toda la información almacenada en el TaskRepository
se modela en esta clase. Es la unidad básica para cada tarea.
Parte de la información almacenada es
executionId
– Id único asociado a la ejecución de la tarea.exitcode
– Código de salida grabado para la tarea.taskName
– Nombre definido por el usuario para la tarea.startTime
– Hora de inicio de la tarea.endTime
– Marca de tiempo de finalización de la tarea.
Ejecutando una tarea
Para ejecutar nuestra tarea, tenemos que implementar el Runner
interfaz y proporcionarlo como un bean en nuestra clase de configuración.
Generalmente, CommandLineRunner
o ApplicationRunner
está implementado:
@Component
public class SampleCommandLineRunner implements CommandLineRunner {
@Override
public void run(String...args) throws Exception {
System.out.println("Specified Task");
}
}
@Configuration
public class TaskConfiguration {
@Bean
public SampleCommandLineRunner sampleCommandLineRunner() {
return new SampleCommandLineRunner();
}
}
Y con eso, de un main
método, podemos llamar al SampleCommandLineRunner
:
@SpringBootApplication
public class SomeApplication {
public static void main(String[] args) {
SpringApplication.run(SampleCommandLineRunner.class, args);
}
}
TaskExecutionListener
Todas TaskExecution
s tienen un ciclo de vida. Spring Cloud Task registra estos eventos. Al comienzo de una tarea, antes de cualquier Runner
se han ejecutado implementaciones de interfaz, una entrada en el TaskRepository
que registra el evento de inicio.
Cuando una tarea se completa o falla, se emite otro evento. TaskExecutionListener
le permite registrar oyentes para escuchar este evento durante todo el ciclo de vida.
Puede especificar tantos oyentes como desee para el mismo evento.
Spring proporciona dos enfoques para hacer esto: usar el TaskExecutionListener
interfaz o el método de anotación de bean.
Para el primero, proporciona un componente que implementa el TaskExecutionListener
interfaz y sus tres métodos:
void onTaskStartup(TaskExecution taskExecution);
void onTaskEnd(TaskExecution taskExecution);
void onTaskFailed(TaskExecution taskExecution, Throwable throwable);
onTaskStartup()
– Invocado después delTaskExecution
ha sido almacenado en elTaskRepository
.onTaskEnd()
– Invocado después delTaskExecution
ha sido actualizado en elTaskRepository
, al finalizar la tarea.onTaskFailed()
– Se invoca si se produce una excepción no detectada durante la ejecución de la tarea.
Por otro lado, utilizando el método de anotación de bean, crea un componente y lo suministra como un bean en su configuración de Spring:
@Configuration
public class AppConfigurtion {
@Bean
public AppTaskListener appTaskListener() {
return new AppTaskListener();
}
}
@Component
class AppTaskListener {
@BeforeTask
public void beforeTaskInvocation(TaskExecution taskExecution) {
System.out.println("Before task");
}
@AfterTask
public void afterTaskInvocation(TaskExecution taskExecution) {
System.out.println("After task");
}
@FailedTask
public void afterFailedTaskInvocation(TaskExecution taskExecution, Throwable throwable) {
System.out.println("Failed task");
}
}
@BeforeTask
es análogo aonTaskStartup()
.@AfterTask
es análogo aonTaskEnd()
.@FailedTask
es análogo aonTaskFailed()
.
Mensajes de salida de tareas
Aunque puede especificar cualquier número de oyentes para un evento en particular, si una excepción es lanzada por un TaskExecutionListener
controlador de eventos, se detiene todo el procesamiento de escucha para ese controlador de eventos.
Por ejemplo, si tres onTaskStartup()
los oyentes han comenzado y el primero onTaskStartup()
El controlador de eventos lanza una excepción, los otros dos onTaskStartup
los métodos no se llaman.
Sin embargo, los otros controladores de eventos (onTaskEnd()
y onTaskFailed()
) Para el TaskExecutionListeners
son llamados.
Cuando ocurren excepciones, el TaskExecutionListener
devuelve un código de salida y un mensaje de salida. Anotar un método con @AfterTask
nos permitirá configurar el mensaje de salida:
@AfterTask
public void afterError(TaskExecution taskExecution) {
taskExecution.setExitMessage("Custom Exit Message");
}
Se puede establecer un mensaje de salida en cualquiera de los eventos de escucha, aunque solo se establecerán los mensajes relevantes. Si una tarea se ejecuta correctamente, onTaskFailed()
el evento no disparará. Cuando finaliza la tarea, el mensaje del onTaskEnd()
El evento está configurado.
Personalización de tareas en la nube
Muchas propiedades pueden ser anuladas por el TaskConfigurer
especificando valores personalizados en el applications.properties
o applications.yaml
archivo.
Las propiedades de la tarea de la nube de Spring tienen el prefijo spring.cloud.task
en el applications.properties
archivo.
Algunas de las propiedades que pueden anularse son:
spring.cloud.task.tablePrefix
– Este es el prefijo de tabla para las tablas de tareas paraTaskRepository
. El prefijo de tabla predeterminado es “TASK_"
.spring.cloud.task.initialize-enabled=false
– Se utiliza para habilitar o deshabilitar la creación de tablas de tareas al inicio de la tarea. Por defecto es verdadero.spring.cloud.task.executionid=yourtaskId
– Esto se usa para configurar Spring Cloud Task para usar su identificación de tarea personalizada. De forma predeterminada, Spring genera un Id. De ejecución de tarea para cada ejecución de tarea.
Para ver más propiedades personalizables, consulte askProperties
.
Registro de eventos de tareas en la nube
Por lo general, es útil durante el desarrollo ver los registros de depuración de la aplicación. Para cambiar el nivel de registro para una tarea de Spring Cloud, agregue esto a su applications.properties
archivo:
logging.level.org.springframework.cloud.task=DEBUG
Conclusión
En este artículo, presentamos Spring Cloud Task, qué es y los problemas que resuelve. También cubrimos ejemplos de cómo configurarlo con una fuente de datos y ejecutar una tarea con el Runner
interfaces.
Además, explicamos la arquitectura Spring Cloud Task y todos los modelos de dominio como TaskExecution
, TaskExecutionListener
, etc. utilizado para lograr todas las funcionalidades.