ThreadPoolTaskExecutor Queue가 full의 처리 정책

2021. 12. 21. 07:00·Daily Develop
반응형

나를 닮았다고 한다...

ThreadPoolTaskExecutor의 RejectedExecutionHandler 설정에 대해서 간단히 살펴보겠습니다.

이번글에서는 RejectedExcecutionHandler의 정책을 설정하는 기준과 설정 시 어떤 결과값이 나오는지 살펴보겠습니다.

 

RejectedExcutionHandler의 종류

  • AboryPolicy
  • CallerRunsPolicy
  • DiscardPolicy
  • DiscardOldestPolicy

 

ThreadPoolTaskExecutor 기본 설정

@Configuration
public class TestThreadPool {

    @Bean
    public TaskExecutor test() {
        var executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);   // 최소 유지 Pool Size
        executor.setMaxPoolSize(200);    // 최대 Pool Size
        executor.setQueueCapacity(100);  // 최대 Pool Size가 초과 후 사용되는 Queue
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());  // Queue를 full로 사용 후 이후 요청처리 방식
        return executor;
    }

}

위처럼 쓰레드풀을 설정할 경우 아래와 같이 작동됩니다.

  1. Request 500개 요청
  2. ThreadPool 300개 먼저 사용
  3. Queue 100개 사용
  4. 나머지 100개의 요청에 대해서 어떻게 처리할 지 RejectedExcutionHandler에서 지정된 정책으로 처리합니다.

 

ThreadPoolExecutor.AbortPolicy

처리되지 못한 100개의 요청에 대해서 org.springframework.core.task.TaskRejectedException 발생되며 요청을 무시합니다.

 

 

ThreadPoolExecutor.CallerRunsPolicy

처리되지 못한 100개의 요청을 ThreadPool을 호출한 Thead에서 처리하게 됩니다.

  • 만약 Tomcat 서버에서 ThreadPool을 호출했다면 Tomcat thread가 요청을 처리합니다.

 

ThreadPoolExecutor.DiscardPolicy

처리되지 못한 100개의 요청을 조용히 무시합니다. 

  • AbortPolicy와 다른점은 Exception을 발생시키지 않고 버립니다.

 

ThreadPoolExecutor.DiscardOldestPolicy

가장 오래된 요청은 삭제하고 다시 execute() 실행

 

 

그렇다면 여기서 궁금한점?

만약 클라이언트에서 호출 후 결과값을 기다린다는 가정이라면 어떨까?

@RestController
@RequiredArgsConstructor
public class TestController {

    private final TaskExecutor executor;

    @GetMapping("/test1")
    public CompletableFuture<ApiResponse<Integer>> teset() {
        return CompletableFuture.supplyAsync(() ->
            getResult(), executor
        ).exceptionally(e -> {
            return ApiResponse.success(1);
        });
    }


    private ApiResponse<Integer> getResult() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ApiResponse.success(1);
    }

}

위 코드를 간략히 설명하면 하나의 Thread에서 처리하는 시간이 길고 클라이언트에서 결과값을 바라는 코드입니다.

 

AbortPolicy와 CallerRunsPolicy를 사용할 경우 어떻게든 결과값을 받게됩니다. 

  • AbortPolicy: Exception
  • CallerRunsPolicy: 응답이 느려질 수 있으나 받을 수 있음

 

그렇다면 DiscardPolicy와 DiscardOldestPolicy는??

결과는 AboryPolicy와 마찬가지로 Exception을 받지만 아래와 Timeout 관련 Exception이 발생합니다. 

org.springframework.web.context.request.async.AsyncRequestTimeoutException: null

 

 

결론

반드시 처리되어야 하는 경우 CallerRunsPolicy를 사용하면 되겠네요. 하지만 Main Thread에 영향을 끼치기 때문에 성능 테스트를 다양하게 하여 Main Thread에도 최소한의 영향을 끼치는 수준으로 설정해야합니다. 

 

클라이언트에서 요청을 원하고 Exception 처리가 필요한 경우는 Discard 보단 AbortPolicy를 사용하는 편이 좋다고 생각합니다. Timeout은 클라이언트에서 요청을 기다리다가 Exception이 발생하기 때문에 속도측면에서 불리하게 작용될 것입니다. 

반응형

'Daily Develop' 카테고리의 다른 글

Intellij에서 QClass 깨끗히 청소하기  (2) 2022.01.11
[JPA] deleteAll() vs deleteAllInBatch()  (0) 2021.07.28
[HttpStatus] API 처리 별 HttpStatus 리턴 코드 정리  (0) 2021.07.13
[코틀린] 한글 깨질 때 인코딩처리  (0) 2021.07.02
[Post] application/x-www-form-urlencoded 데이터 받는 방법, inputStream 주의  (3) 2021.06.18
'Daily Develop' 카테고리의 다른 글
  • Intellij에서 QClass 깨끗히 청소하기
  • [JPA] deleteAll() vs deleteAllInBatch()
  • [HttpStatus] API 처리 별 HttpStatus 리턴 코드 정리
  • [코틀린] 한글 깨질 때 인코딩처리
에디개발자
에디개발자
------ 한발자국씩 성장하자 ------ Github: https://github.com/yongtaelim LinkedIn: https://www.linkedin.com/in/%EC%9A%A9%ED%83%9C-%EC%9E%84-622b69218/
    250x250
  • 에디개발자
    에디블로그
    에디개발자
    • 분류 전체보기 (245) N
      • Develop (51)
        • spring-data (28)
        • spring-batch (7)
        • devops (5)
        • java (5)
        • kotlin (3)
        • database (2)
      • MindControl (12)
      • TroubleShooting (16)
      • Study (76)
        • kotlin (16)
        • java (15)
        • spring (6)
        • test (4)
        • message-queue (10)
        • object (22)
      • Develop Tool (1)
      • Daily Develop (7)
      • Book (5)
      • AI (56) N
        • Claude (23) N
        • ChatGPT (11) N
        • Cursor (10) N
        • Gemini (8) N
        • 트랜드 (4) N
      • 개발 트렌드 (17) N
        • 데일리 픽 (17) N
        • 툴 리뷰 (0)
      • 개발자 도구 (0)
        • 생산성 툴 (0)
        • 노트 & 지식관리 (0)
        • 협업 & 이슈 (0)
        • 터미널 & 환경 (0)
        • API & DB (0)
        • 에디터 & IDE (0)
  • 인기 글

  • 태그

    엘레강트
    스터디
    개발자 도구
    AI 활용
    에디
    cursor
    객체지향
    claude code
    anthropic
    queryDSL
    ChatGPT
    OpenAI
    ai 정보
    JPA
    claude
    Ai
    ai 코딩
    코틀린
    프로그래밍
    클로드
  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에디개발자
ThreadPoolTaskExecutor Queue가 full의 처리 정책
상단으로

티스토리툴바