사용자 도구

사이트 도구


springframework:async

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
springframework:async [2019/01/15 11:01]
kwon37xi
springframework:async [2023/01/26 10:20] (현재)
kwon37xi [ThreadPoolTaskExecutor 설정]
줄 2: 줄 2:
   * [[http://www.baeldung.com/spring-async|Spring Async]]   * [[http://www.baeldung.com/spring-async|Spring Async]]
   * [[https://docs.spring.io/spring/docs/4.1.x/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html|ThreadPoolTaskExecutor]]로 비동기 코드 실행   * [[https://docs.spring.io/spring/docs/4.1.x/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html|ThreadPoolTaskExecutor]]로 비동기 코드 실행
 +  * [[java:concurrent:executorservice|Java ExecutorService]]
 +  * 비동기 작업시 [[springframework:bean_lifecycle|Spring Framework Bean Lifecycle]]에 있는 ''SmartLifeCycle''을 구현해줘야만 한다.
  
 ===== 설정 ===== ===== 설정 =====
줄 20: 줄 22:
  
 ===== ThreadPoolTaskExecutor 설정 ===== ===== ThreadPoolTaskExecutor 설정 =====
-  * [[java:concurrent:executorservice|Java ExecutorService]] 참조 +  * [[java:concurrent:executorservice|Java ExecutorService]] 참조 Spring 의 ThreadPool 
-  * wait 설정으로 서버 종료시 남은 작업을 기다릴 시간 확보+  * wait 설정으로 서버 종료시 남은 작업을 기다릴 시간 확보해야함. 아래를 안해주면 서버가 그냥 종료 돼 버린다.
   * ''waitForTasksToCompleteOnShutdown=true''   * ''waitForTasksToCompleteOnShutdown=true''
   * ''awaitTerminationSeconds=초''   * ''awaitTerminationSeconds=초''
 +  * ''beanName''을 지정해주면 로그에 이름이 찍힘.
 +  * [[https://github.com/kwon37xi/java-spring-thread-pool-test|kwon37xi/java-spring-thread-pool-test: Java와 SpringFramework 의 Thread Pool 작동 방식 테스트]]
 +    * fixed? cached?
 +  * 서버 종료시 올바로 종료됨을 보장하려면 [[springframework:bean_lifecycle|Spring Framework Bean Lifecycle]] [[https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html|SmartLifeCycle]]도 구현해야한다.
  
 ===== Cached Thread Pool 효과 ===== ===== Cached Thread Pool 효과 =====
-  * QueueCapacity를 0으로 만들면 Cached Thread Pool 처럼 작동한다. +  * corePoolSize 는 적게 혹은 0, maxPoolSize=''Interger.MAX_VALUE'', queueCapacity를 0으로 만들면 Cached Thread Pool 처럼 작동한다. 
   * 기본 CorePoolSize 만큼 풀을 생성하고,   * 기본 CorePoolSize 만큼 풀을 생성하고,
-  * 필요하면 쓰레드풀을 최대 MaxPoolSize 만큼 증가시키고+  * 필요하면 쓰레드풀을 최대 maxPoolSize 만큼 증가시키고
   * 안 사용하는 시간이 KeepAliveSeconds가 지나면 쓰레드를 없앤다.   * 안 사용하는 시간이 KeepAliveSeconds가 지나면 쓰레드를 없앤다.
 +  * cachedThreadPool 은 느려지는 태스크 실행시 쓰레드 갯수가 폭증해서 시스템을 다운시킬 수도 있다.
  
 <code java> <code java>
 ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
 threadPoolTaskExecutor.setThreadNamePrefix("XXXX-"); threadPoolTaskExecutor.setThreadNamePrefix("XXXX-");
-threadPoolTaskExecutor.setCorePoolSize(10);+threadPoolTaskExecutor.setCorePoolSize(0);
 threadPoolTaskExecutor.setMaxPoolSize(Integer.MAX_VALUE); threadPoolTaskExecutor.setMaxPoolSize(Integer.MAX_VALUE);
 threadPoolTaskExecutor.setQueueCapacity(0); threadPoolTaskExecutor.setQueueCapacity(0);
줄 71: 줄 77:
         // Right now: @Async thread context !         // Right now: @Async thread context !
         // (Restore the Web thread context's MDC data)         // (Restore the Web thread context's MDC data)
-        MDC.setContextMap(contextMap);+        if (contextMap != null) { 
 +            MDC.setContextMap(contextMap); 
 +        } 
         runnable.run();         runnable.run();
       } finally {       } finally {
줄 83: 줄 92:
  
 ===== CompletableFuture 지원 ===== ===== CompletableFuture 지원 =====
 +  * [[java:8:completable_future|Java 8 CompletableFuture]]
   * [[https://www.javacodegeeks.com/2016/04/spring-async-javas-8-completablefuture.html|Spring Async and Java's 8 CompletableFuture]]   * [[https://www.javacodegeeks.com/2016/04/spring-async-javas-8-completablefuture.html|Spring Async and Java's 8 CompletableFuture]]
 +  * [[https://spring.io/guides/gs/async-method/|Getting Started | Creating Asynchronous Methods]]
 +  * [[https://dzone.com/articles/spring-boot-async-methods|Spring Boot - Async methods - DZone Java]]
 +
 +  * 아래와 같이 ''CompletableFuture.completedFuture()''를 리턴하게 만들면 Spring 이 내부적으로 [[https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncExecutionInterceptor.html|AsyncExecutionInterceptor]]에서 진짜 ''CompletableFuture.supplyAsync''로 변환해서 리턴한다. [[https://github.com/spring-projects/spring-framework/blob/master/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java|AsyncExecutionAspectSupport.java 소스]] [[https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/concurrent/ListenableFuture.html|ListenableFuture]]와 [[https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html|Future]]도 마찬가지로 작동함.
 +<code java>
 +@Async
 +public CompletableFuture<User> findUser(String user) throws InterruptedException {
 +    logger.info("Looking up " + user);
 +    String url = String.format("https://api.github.com/users/%s", user);
 +    User results = restTemplate.getForObject(url, User.class);
 +    Thread.sleep(1000L);
 +    return CompletableFuture.completedFuture(results); //IT IS completedFuture
 +}
 +</code>
springframework/async.1547517693.txt.gz · 마지막으로 수정됨: 2019/01/15 11:01 저자 kwon37xi