ν‹°μŠ€ν† λ¦¬ λ·°

Spring MVCμ—μ„œ ν”„λ‘œμ„ΈμŠ€λŠ” 기본적으둜 동기식 처리둜 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

μ½”λ“œ ν•œμ€„ν•œμ€„ μ°¨λ‘€λŒ€λ‘œ 싀행이 μ™„λ£Œλœ ν›„ λ„˜μ–΄κ°ˆ 수 μžˆλ‹€λŠ” 뜻이죠. 보톡 이걸 Blocking 이라고 ν•˜κ³  λ°˜λŒ€κ°€ λ˜λŠ” 말은 Non-Blocking 이라고 ν•©λ‹ˆλ‹€. μ½”λ“œκ°€ μ°¨λ‘€λŒ€λ‘œ μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έμ— μ½”λ“œ 싀행에 λ”°λ₯Έ κ²°κ³Ό 값을 λ³΄λŠ”κ²Œ λͺ…ν™•ν•œ μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

 

Node.js둜 κ°œλ°œμ„ μ’€ ν•΄μ˜€λ‹€λ³΄λ‹ˆ (Node.jsλŠ” λ°˜λŒ€λ‘œ λΉ„λ™κΈ°μ²˜λ¦¬κ°€ κΈ°λ³Έ μ»¨μ…‰μž…λ‹ˆλ‹€.) Async에 λŒ€ν•œ μš©μ–΄μ— 더 λˆˆμ΄κ°€μ„œ Spring μ–΄λ…Έν…Œμ΄μ…˜μ€‘ @Async μ–΄λ…Έν…Œμ΄μ…˜μ— λ¨Όμ € 눈이 κ°”μŠ΅λ‹ˆλ‹€. μ–΄λ…Έν…Œμ΄μ…˜ ν•˜λ‚˜λ§Œ μΆ”κ°€ν•˜λ©΄ λ‚΄κ°€ μ›ν•˜λŠ”κ²Œ λœλ‹€?

 

@Async

@AsyncλŠ” Spring ν”„λ ˆμž„μ›Œν¬μ—μ„œ 비동기적인 λ©”μ„œλ“œ 싀행을 μ§€μ›ν•˜κΈ° μœ„ν•œ μ–΄λ…Έν…Œμ΄μ…˜μž…λ‹ˆλ‹€. 이 μ–΄λ…Έν…Œμ΄μ…˜μ„ λ©”μ„œλ“œμ— 뢙이면 ν•΄λ‹Ή λ©”μ„œλ“œλŠ” λ³„λ„μ˜ μ“°λ ˆλ“œμ—μ„œ μ‹€ν–‰λ˜λ©°, ν˜ΈμΆœν•œ μ“°λ ˆλ“œλŠ” λ©”μ„œλ“œκ°€ μ™„λ£Œλ  λ•ŒκΉŒμ§€ λΈ”λ‘œν‚Ήλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. @Asyncλ₯Ό μ‚¬μš©ν•˜λ©΄ 동기적인 방식이 μ•„λ‹Œ 비동기적인 λ°©μ‹μœΌλ‘œ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

λ©”μ†Œλ“œμ— κ·Έλƒ₯ μ–΄λ…Έν…Œμ΄μ…˜λ§Œ 뢙이면 Async λ©”μ†Œλ“œκ°€ λ˜λŠ” 것인가? ν–ˆμ§€λ§Œ @Asyncλ₯Ό μ‚¬μš©ν•  λ•Œ μ£Όμ˜ν•  점은 이 μ–΄λ…Έν…Œμ΄μ…˜λ„ Thread pool을 μ‚¬μš©ν•˜λŠ” 것이기 λ•Œλ¬Έμ— λ¬΄λΆ„λ³„ν•˜κ²Œ μ‚¬μš©ν•˜λ©΄ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•  μˆ˜λ„ 있고, μŠ€ν”„λ§μ˜ ν”„λ‘μ‹œ λ§€μ»€λ‹ˆμ¦˜μ„ 톡해 비동기 μ²˜λ¦¬κ°€ κ΅¬ν˜„λ˜κΈ° λ•Œλ¬Έμ— @Async λ©”μ„œλ“œλŠ” 같은 클래슀 λ‚΄μ—μ„œ 호좜되면 λΉ„λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 이 경우 AOP ν”„λ‘μ‹œκ°€ μ μš©λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

 

저같은 κ²½μš°λ„ Spring MVC ν”„λ‘œμ νŠΈμ— 기본적으둜 Filterλ₯Ό μ‚¬μš©ν•˜κ³ μžˆλŠ”λ° μœ„ λ‚΄μš©λ•Œλ¬Έμ— μ œλŒ€λ‘œ μž‘λ™ν•˜μ§€ μ•ŠλŠ” 뢀뢄을 ν™•μΈν•˜κ³  λ°”λ‘œ λ‹€λ₯Έ 방법을 μ°Ύμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

 

ThreadPoolTaskExecutor

μŠ€ν”„λ§μ—μ„œ μ œκ³΅ν•΄μ£ΌλŠ” 클래슀둜 μ“°λ ˆλ“œν’€μ„ μ΄μš©ν•˜μ—¬ λ©€ν‹°μ“°λ ˆλ“œ κ΅¬ν˜„μ„ μ‰½κ²Œ ν•΄μ£ΌλŠ” ν΄λž˜μŠ€μž…λ‹ˆλ‹€.

일단 μ œκ°€ μ˜λ„ν•œ 뢀뢄은 API 호좜 μ‹œμ— λ‚΄λΆ€ μ²˜λ¦¬μ™€ 상관없이 λΉ λ₯΄κ²Œ 응닡 값을 μ£ΌλŠ”κ±Έ μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬κΈ°μœ„ν•΄μ„  λΆ€ν•˜κ°€ 큰 Service λ©”μ†Œλ“œμ— λŒ€ν•œ Async μ²˜λ¦¬κ°€ ν•„μš”ν–ˆκ³ , μ•„λž˜μ™€κ°™μ΄ μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.

 

AsyncConfig.class

: μ“°λ ˆλ“œν’€μ„ μ‚¬μš©ν•˜κΈ° μœ„ν•œ custom 섀정을 ν•˜λŠ” ν΄λž˜μŠ€μž…λ‹ˆλ‹€.

@Configuration
public class AsyncConfig {

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);  // μ“°λ ˆλ“œν’€μ˜ κΈ°λ³Έ 크기
        executor.setMaxPoolSize(50);   // μ“°λ ˆλ“œν’€μ˜ μ΅œλŒ€ 크기
        executor.setQueueCapacity(100); // μž‘μ—… 큐 크기
        executor.setThreadNamePrefix("Custom-Async-"); // μ“°λ ˆλ“œ 이름 접두사 μ„€μ •
        executor.initialize();
        return executor;
    }
}

 

Controllerμ½”λ“œ

: μ„œλΉ„μŠ€ λ©”μ†Œλ“œλ₯Ό λ°±κ·ΈλΌμš΄λ“œ 둜직으둜 μˆ˜μ •ν•˜μ˜€κ³ , DeferredResult 객체에 λΉ„λ™κΈ°λ‘œμ§μ— λŒ€ν•œ κ²°κ³Ό 값을 μ €μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

@RequiredArgsConstructor
public class AlarmController {
    private final AlarmService alarmService;
    @Qualifier("taskExecutor")
    private final ThreadPoolTaskExecutor taskExecutor;

   @PostMapping(value = "/{id}/send")
   public Response<Map<String,Object>> immediatelyPush(
           HttpServletRequest req,
           @PathVariable("id") Long id
   ) {
       try {
           // DeferredResult<Response<Map<String, Object>>> deferredResult = new DeferredResult<>();

           taskExecutor.submit(() -> {
               // λΉ„λ™κΈ°λ‘œ μ‹€ν–‰λ˜λŠ” λ°±κ·ΈλΌμš΄λ“œ 둜직
               alarmService.immediatelyPush(id);
               // deferredResult.setResult(new Response<>(ResultCode.REGISTER_SUCCESS));
               // deferredResult.setResult(new Response<>(ResultCode.REGISTER_FAIL));
           });
           return new Response<>(ResultCode.REGISTER_SUCCESS);
       } catch (Exception e) {
           return new Response<>(ResultCode.REGISTER_FAIL);
       }
   }
}

μ΄λ ‡κ²Œλ˜λ©΄ μ„œλΉ„μŠ€ λ©”μ†Œλ“œμ— λŒ€ν•œ 뢀뢄이 μ‹€ν–‰μ™„λ£Œλ˜μ§€μ•Šμ•„λ„ μ¦‰μ‹œ responseλ₯Ό λ„˜κ²¨μ£Όκ²Œ λ©λ‹ˆλ‹€. λ¬Όλ‘  response후에도 Spring Application μ—μ„œλŠ” ν•΄λ‹Ή 둜직이 μ‹€ν–‰μ€‘μ΄κ²Œ λ©λ‹ˆλ‹€.

 

 

'springπŸƒ' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

Spring bootμ—μ„œ Http request 비동기 μš”μ²­ν•˜κΈ°  (0) 2023.10.26
λŒ“κΈ€
곡지사항
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€
Total
Today
Yesterday
링크
Β«   2024/11   Β»
일 μ›” ν™” 수 λͺ© 금 ν† 
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
κΈ€ 보관함