J'ai étudié ce qui est nécessaire pour le traitement asynchrone avec SpringBoot, donc dans ce document,
J'ai résumé sur.
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')
}
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);
}
}
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;
}
}
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;
}
}
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
Recommended Posts