[JAVA] Traitement asynchrone avec Spring Boot en utilisant @Async

À propos de ce document

J'ai étudié ce qui est nécessaire pour le traitement asynchrone avec SpringBoot, donc dans ce document,

  1. Méthode de traitement asynchrone utilisant @Async
  2. Configuration des threads à l'aide de TaskExcecuter

J'ai résumé sur.

Environnement d'exécution

java8 + Spring Boot 2.1.0 + lombok

build.gradle est le suivant


buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    compileOnly('org.projectlombok:lombok')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}

Essayer

Implémentez le processus que vous souhaitez exécuter de manière asynchrone

la mise en oeuvre

Créez un processus qui dort correctement

@Slf4j
@Service
public class AsyncService {

    @Async("Thread2")
    public CompletableFuture<String> findName(String name, Long sleepTime) throws InterruptedException {
        log.warn("Async function started. processName: " + name + "sleepTime: " + sleepTime);
        Thread.sleep(sleepTime);
        
        //Utilisez la valeur de retour que vous souhaitez réellement utiliser dans le Completable Future afin de pouvoir gérer le traitement asynchrone.
        return CompletableFuture.completedFuture(name);
    }

}
Commentaire

Mettre en œuvre le processus d'appel et de gestion de la logique ci-dessus

la mise en oeuvre

Implémentez un contrôleur approprié pour gérer le traitement asynchrone


@Slf4j
@RequiredArgsConstructor
@RestController
public class FindNameContoller {

    private final AsyncService asyncService;

    @GetMapping("/users/")
    public List<String> findUsers() throws Exception {
        long start = System.currentTimeMillis();
        long heavyProcessTime = 3000L;
        long lightProcessTime = 1000L;

        log.warn("request started");
        CompletableFuture<String> heavyProcess = asyncService.findName("heavy", heavyProcessTime);
        CompletableFuture<String> lightProcess = asyncService.findName("light", lightProcessTime);

        //Processus à exécuter lorsque heavyProcess est terminé
        heavyProcess.thenAcceptAsync(heavyProcessResult -> {
            log.warn("finished name=" + heavyProcessResult + ", sleep = " + heavyProcessTime);
        });

        //Processus à exécuter lorsque lightProcess est terminé
        lightProcess.thenAcceptAsync(lightProcessResult -> {
            log.warn("finished name=" + lightProcessResult + ", sleep = " + lightProcessTime);
        });

        //Lorsque le processus spécifié est terminé, les processus suivants seront exécutés.
        CompletableFuture.allOf(heavyProcess, lightProcess).join();

        //Créer une valeur de retour
        List<String> names = new ArrayList<>();
        names.add(heavyProcess.get());
        names.add(lightProcess.get());

        Thread.sleep(10L);

        long end = System.currentTimeMillis();
        //Sortie de l'heure de l'ensemble du processus
        log.warn("request finished. time: " + ((end - start))  + "ms");

        return names;
    }

}
Commentaire

Définissez la limite supérieure de Thread, etc.

la mise en oeuvre

Décrire les différents paramètres de la classe Application principale


@EnableAsync
@SpringBootApplication
public class AsyncTrainingApplication {

    public static void main(String[] args) {
        SpringApplication.run(AsyncTrainingApplication.class, args);
    }

    @Bean("Thread1") //Ce paramètre n'est pas spécifié et n'est pas utilisé
    public Executor taskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setThreadNamePrefix("Thread1--");
        executor.initialize();
        return executor;
    }

    @Bean("Thread2") //Définir ici"Thread2"Est défini sur @Async et ce paramètre est utilisé
    public Executor taskExecutor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); //La taille de filetage par défaut. Lorsqu'il déborde, il indique la taille de la capacité de la file d'attente
        executor.setQueueCapacity(1); //La taille de la file d'attente. Augmenter le filetage à la taille maximale du pool en cas de débordement
        executor.setMaxPoolSize(500); //Définition de la quantité de fil à augmenter S'il dépasse cette valeur, le processus sera rejeté et une exception se produira.
        executor.setThreadNamePrefix("Thread2--");
        executor.initialize();
        return executor;
    }

    @Bean("Reject") //Avec ce paramètre, la mise en file d'attente ne peut pas être effectuée, le thread ne peut pas être augmenté et une exception RejectedExecutionException se produit.
    public Executor rejectTaskExecuter() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setQueueCapacity(0);
        executor.setMaxPoolSize(1);
        executor.setThreadNamePrefix("Reject--");
        executor.initialize();
        return executor;
    }

}
Commentaire

Exécuter

Lorsque vous exécutez le processus, le journal suivant apparaît et vous pouvez voir qu'il s'exécute de manière asynchrone

2018-11-27 20:19:13.181  WARN 8711 --- [nio-8080-exec-5] c.e.asynctraining.FindNameContoller      : request started
2018-11-27 20:19:13.181  WARN 8711 --- [TaskExecutor-31] com.example.asynctraining.AsyncService   : Async function started. processName: heavysleepTime: 3000
2018-11-27 20:19:13.182  WARN 8711 --- [TaskExecutor-32] com.example.asynctraining.AsyncService   : Async function started. processName: lightsleepTime: 1000
2018-11-27 20:19:14.187  WARN 8711 --- [onPool-worker-2] c.e.asynctraining.FindNameContoller      : finished name=light, sleep = 1000
2018-11-27 20:19:16.182  WARN 8711 --- [onPool-worker-2] c.e.asynctraining.FindNameContoller      : finished name=heavy, sleep = 3000
2018-11-27 20:19:16.194  WARN 8711 --- [nio-8080-exec-5] c.e.asynctraining.FindNameContoller      : request finished. time: 3013ms

Résumé approximatif

Impressions

Matériaux référencés

Recommended Posts

Traitement asynchrone avec Spring Boot en utilisant @Async
Traitement asynchrone avec exécution régulière dans Spring Boot
Spring avec Kotorin --6 Traitement asynchrone
Essayez d'utiliser Spring Boot avec VS Code
Télécharger avec Spring Boot
Exécutez un traitement arbitraire après l'authentification de base avec Spring Boot.
Essayez d'utiliser un conteneur DI avec Laravel et Spring Boot
Générer un code à barres avec Spring Boot
Hello World avec Spring Boot
Implémenter GraphQL avec Spring Boot
Essayez d'utiliser OpenID Connect avec Keycloak (application Spring Boot)
Démarrez avec Spring Boot
[Compatible JUnit 5] Ecrire un test en utilisant JUnit 5 avec Spring boot 2.2, 2.3
Bonjour tout le monde avec Spring Boot!
Téléchargement de fichiers avec Spring Boot
Spring Boot commençant par copie
Utilisation de Mapper avec Java (Spring)
Spring Boot à partir de Docker
Hello World avec Spring Boot
Définir des cookies avec Spring Boot
Utiliser Spring JDBC avec Spring Boot
Ajouter un module avec Spring Boot
Premiers pas avec Spring Boot
Essayez d'utiliser Spring Boot Security
[Swift] Traitement asynchrone à l'aide de PromiseKit
Créer un micro service avec Spring Boot
Envoyer du courrier avec Spring Boot
Exécution du traitement initial à l'aide de Spring Boot Command Line Runner
J'ai essayé de démarrer avec Swagger en utilisant Spring Boot
Utiliser l'authentification de base avec Spring Boot
gRPC sur Spring Boot avec grpc-spring-boot-starter
Créez une application avec Spring Boot 2
Déploiement à chaud avec le développement Spring Boot
Liaison de base de données avec doma2 (Spring boot)
Tutoriel Spring Boot à l'aide de l'authentification Spring Security
Programmation Spring Boot avec VS Code
Jusqu'à "Hello World" avec Spring Boot
Créer une application d'enquête avec Spring Boot
Obtenez des résultats de validation avec Spring Boot
(Intellij) Hello World avec Spring Boot
Créez une application avec Spring Boot
Google Cloud Platform avec Spring Boot 2.0.0
J'ai essayé GraphQL avec Spring Boot
[Java] Intégration LINE avec Spring Boot
À partir de Spring Boot 0. Utilisez Spring CLI
J'ai essayé Flyway avec Spring Boot
La coopération des messages a commencé avec Spring Boot
Partie 1: Essayez d'utiliser la connexion OAuth 2.0 prise en charge par Spring Security 5 avec Spring Boot
Image de l'application Spring Boot à l'aide de jib-maven-plugin et lancez-la avec Docker
Hello World avec Eclipse + Spring Boot + Maven
Envoyez des notifications régulières avec LineNotify + Spring Boot
HTTPS avec Spring Boot et Let's Encrypt
Démarrez le développement d'applications Web avec Spring Boot
Lancez l'application Nginx + Spring Boot avec docker-compose
J'ai essayé l'initialisation paresseuse avec Spring Boot 2.2.0
Implémenter CRUD avec Spring Boot + Thymeleaf + MySQL
Implémenter la fonction de pagination avec Spring Boot + Thymeleaf
(IntelliJ + gradle) Hello World avec Spring Boot