Une introduction à la tâche Cloud Spring

Une introduction à la tâche Cloud Spring

1. Vue d'ensemble

The goal of Spring Cloud Task is to provide the functionality of creating short-lived microservices for Spring Boot application.

Dans Spring Cloud Task, nous avons la flexibilité d'exécuter n'importe quelle tâche de manière dynamique, d'allouer des ressources à la demande et de récupérer les résultats une fois la tâche terminée.

Tasks is a new primitive within Spring Cloud Data Flow allowing users to execute virtually any Spring Boot application as a short-lived task.

2. Développement d'une application de tâche simple

2.1. Ajout de dépendances pertinentes

Pour commencer, nous pouvons ajouter une section de gestion des dépendances avecspring-cloud-task-dependencies:


    
        
            org.springframework.cloud
            spring-cloud-task-dependencies
            1.2.2.RELEASE
            pom
            import
        
    

Cette gestion des dépendances gère les versions des dépendances via l'étendue d'importation.

Nous devons ajouter les dépendances suivantes:


    org.springframework.cloud
    spring-cloud-starter-task


    org.springframework.cloud
    spring-cloud-task-core

This est le lien vers le Maven Central despring-cloud-task-core.

Maintenant, pour démarrer notre application Spring Boot, nous avons besoin despring-boot-starter avec le parent concerné.

Nous allons utiliser Spring Data JPA comme outil ORM, nous devons donc également ajouter la dépendance pour cela:


    org.springframework.boot
    spring-boot-starter-data-jpa
    1.5.10

Les détails de l'amorçage d'une simple application Spring Boot avec Spring Data JPA sont disponibleshere.

Nous pouvons vérifier la dernière version desspring-boot-starter-parent onMaven Central.

2.2. L'annotation@EnableTask

Pour amorcer la fonctionnalité de Spring Cloud Task, nous devons ajouter l'annotation@EnableTask:

@SpringBootApplication
@EnableTask
public class TaskDemo {
    // ...
}

The annotation brings SimpleTaskConfiguration class in the picture which in turns registers the TaskRepository and its infrastructure. Par défaut, une carte en mémoire est utilisée pour stocker l'état desTaskRepository.

Les informations primaires deTaskRepository sont modélisées dans la classeTaskExecution. Les champs notés de cette classe sonttaskName,startTime,endTime,exitMessage. LeexitMessage stocke les informations disponibles au moment de la sortie.

Si une sortie est provoquée par une défaillance dans l'un des événements de l'application, la trace complète de la pile des exceptions sera stockée ici.

Spring Boot provides an interface ExitCodeExceptionMapper which maps uncaught exceptions to exit codes allowing scrutinized debug. La tâche en nuage stocke les informations dans la source de données pour une analyse ultérieure.

2.3. Configuration d'unDataSource pourTaskRepository

La carte en mémoire pour stocker lesTaskRepository disparaîtra une fois la tâche terminée et nous perdrons les données liées aux événements de tâche. Pour stocker dans un stockage permanent, nous allons utiliser MySQL comme source de données avec Spring Data JPA.

La source de données est configurée dans le fichierapplication.yml. Pour configurer Spring Cloud Task afin d'utiliser la source de données fournie comme stockage deTaskRepository, nous devons créer une classe qui étendDefaultTaskConfigurer.

Maintenant, nous pouvons envoyer desDatasource configurés en tant qu'argument de constructeur au constructeur de la superclasse:

@Autowired
private DataSource dataSource;

public class HelloWorldTaskConfigurer extends DefaultTaskConfigurer{
    public HelloWorldTaskConfigurer(DataSource dataSource){
        super(dataSource);
    }
}

Pour avoir la configuration ci-dessus en action, nous devons annoter une instance deDataSource avec l'annotation@Autowired et injecter l'instance comme argument constructeur d'un beanHelloWorldTaskConfigurer défini ci-dessus:

@Bean
public HelloWorldTaskConfigurer getTaskConfigurer() {
    return new HelloWorldTaskConfigurer(dataSource);
}

Ceci termine la configuration pour stockerTaskRepository dans la base de données MySQL.

2.4. la mise en oeuvre

Dans Spring Boot,we can execute any Task just before application finishes its startup. Nous pouvons utiliser les interfacesApplicationRunner ouCommandLineRunner pour créer une tâche simple.

Nous devons implémenter la méthoderun de ces interfaces et déclarer la classe d'implémentation comme un bean:

@Component
public static class HelloWorldApplicationRunner
  implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments arg0) throws Exception {
        System.out.println("Hello World from Spring Cloud Task!");
    }
}

Maintenant, si nous exécutons notre application, notre tâche devrait générer la sortie nécessaire avec les tables requises créées dans notre base de données MySQL et consignant les données d'événement de la tâche.

3. Cycle de vie d'une tâche Spring Cloud

Au début, nous créons une entrée dans lesTaskRepository. Ceci indique que tous les beans sont prêts à être utilisés dans l’application et que la méthoderun de l’interface Runner est prête à être exécutée.

À la fin de l'exécution de la méthoderun ou en cas d'échec de l'événementApplicationContext,TaskRepository sera mis à jour avec une autre entrée.

During the task life-cycle, we can register listeners available from TaskExecutionListener interface. Nous avons besoin d'une classe implémentant l'interface ayant trois méthodes -onTaskEnd,onTaksFailed etonTaskStartup déclenchées dans les événements respectifs de la tâche.

Nous devons déclarer le bean de la classe d'implémentation dans notre classeTaskDemo:

@Bean
public TaskListener taskListener() {
    return new TaskListener();
}

4. Intégration avec Spring Batch

Nous pouvons exécuter Spring Batch Job en tant que tâche et enregistrer les événements de son exécution à l'aide de Spring Cloud Task. Pour activer cette fonctionnalité, nous devons ajouter des dépendances Batch relatives à Boot et Cloud:


    org.springframework.boot
    spring-boot-starter-batch


    org.springframework.cloud
    spring-cloud-task-batch

Here est le lien vers le Maven Central despring-cloud-task-batch.

Pour configurer un travail en tant que tâche, nous devons avoir le bean Job enregistré dans la classeJobConfiguration:

@Bean
public Job job2() {
    return jobBuilderFactory.get("job2")
      .start(stepBuilderFactory.get("job2step1")
      .tasklet(new Tasklet(){
          @Override
          public RepeatStatus execute(
            StepContribution contribution,
            ChunkContext chunkContext) throws Exception {
            System.out.println("This job is from example");
                return RepeatStatus.FINISHED;
          }
    }).build()).build();
}

We need to decorate the TaskDemo class with @EnableBatchProcessing annotation:

//..Other Annotation..
@EnableBatchProcessing
public class TaskDemo {
    // ...
}

L'annotation@EnableBatchProcessing active les fonctionnalités Spring Batch avec une configuration de base requise pour configurer des travaux par lots.

Désormais, si nous exécutons l'application, l'annotation@EnableBatchProcessing déclenchera l'exécution du Job Spring Batch et Spring Cloud Task enregistrera les événements des exécutions de tous les jobs batch avec l'autre Tâche exécutée dans la base de donnéesspringcloud .

5. Lancement d'une tâche à partir du flux

Nous pouvons déclencher des tâches à partir de Spring Cloud Stream. Pour atteindre cet objectif, nous avons l'annotation@EnableTaskLaucnher. Une fois que nous avons ajouté l'annotation avec l'application Spring Boot, un TaskSink sera disponible:

@SpringBootApplication
@EnableTaskLauncher
public class StreamTaskSinkApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskSinkApplication.class, args);
    }
}

LeTaskSink reçoit le message d'un flux qui contient unGenericMessage contenantTaskLaunchRequest comme charge utile. Ensuite, il déclenche une tâche basée sur les coordonnées fournies dans la demande de lancement de tâche.

To have TaskSink functional, we require a bean configured that implements TaskLauncher interface. À des fins de test, nous nous moquons de la mise en œuvre ici:

@Bean
public TaskLauncher taskLauncher() {
    return mock(TaskLauncher.class);
}

Nous devons noter ici que l'interfaceTaskLauncher n'est disponible qu'après l'ajout de la dépendancespring-cloud-deployer-local:


    org.springframework.cloud
    spring-cloud-deployer-local
    1.3.1.RELEASE

Nous pouvons tester si la tâche est lancée en appelantinput de l'interfaceSink:

public class StreamTaskSinkApplicationTests {

    @Autowired
    private Sink sink;

    //
}

Maintenant, nous créons une instance deTaskLaunchRequest et l'envoyons en tant que charge utile de l'objetGenericMessage<TaskLaunchRequest>. Ensuite, nous pouvons invoquer le canalinput desSink en gardant l'objetGenericMessage dans le canal.

6. Conclusion

Dans ce didacticiel, nous avons exploré le fonctionnement de Spring Cloud Task et comment le configurer pour enregistrer ses événements dans une base de données. Nous avons également observé comment le travail Spring Batch est défini et stocké dans lesTaskRepository. Enfin, nous avons expliqué comment déclencher Task à partir de Spring Cloud Stream.

Comme toujours, le code est disponibleover on GitHub.