ν°μ€ν 리 λ·°
Spring MVCμ λΉλκΈ°μ²λ¦¬ (ThreadPoolTaskExecutor μ¬μ©)
λλμ΄λ°πΎ 2023. 8. 22. 11:47Spring 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
- DeferredResult
- Promise error
- λΉλκΈ° μμ²
- node.js backend
- μκ³ λ¦¬μ¦
- νλ‘κ·Έλλ¨Έμ€
- NestJS
- nestjs typeorm
- @nestjs/config
- backend-framework
- nestjs config
- nestjs/cli
- JavaScript
- nestjs configService
- Promise bulk
- nestjs doc
- node.js
- typeorm μ°κ²°
- κΈ°μμ²API
- foreignkey
- docker mysql
- nestjs module
- typeorm
- nestjs directory
- Spring
- android
- Request_Limit_Exceeded
- sequelize
- Spring Async
- nestjs project
μΌ | μ | ν | μ | λͺ© | κΈ | ν |
---|---|---|---|---|---|---|
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 |