Guía para la tarea de Spring Cloud: microservicios de Spring Boot de corta duración

    Introducción

    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 TaskExecutionsetc.

    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 TaskExecutions 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 del TaskExecution ha sido almacenado en el TaskRepository.
    • onTaskEnd() – Invocado después del TaskExecution ha sido actualizado en el TaskRepository, 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 a onTaskStartup().
    • @AfterTask es análogo a onTaskEnd().
    • @FailedTask es análogo a onTaskFailed().

    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 para TaskRepository. 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.

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *