Spring Scheduler & Async 처리 흐름 - 정기 작업과 비동기 실행 완전 정복
2025. 7. 15. 19:53ㆍFramework/Spring
✅1. @Scheduled - 스케줄링 처리의 핵심
📌기본 개념
- @Scheduled는 정해진 주기마다 메서드를 실행하는 어노테이션이다.
- 백그라운드에서 자동으로 실행되며 주로 배치 작업, 통계 집계, 외부 API 호출 등 반복 작업에 사용
🔧 사용 전 설정
@Configuration
@EnableScheduling
public class SchedulerConfig {
}
@Component
public class SampleScheduler {
@Scheduled(fixedDelay = 5000)
public void task() {
System.out.println("5초마다 실행");
}
}
2. 다양한 실행 옵션
| 속성 | 설명 |
| fixedRate | 메서드 시작 시점 기준 반복 (밀리초) |
| fixedDelay | 메서드 종료 시점 기준 반복 (밀리초) |
| initialDealy | 최초 실행 지연 시간 |
| cron | CRON 표현식 기반 |
@Scheduled(fixedRate = 10000) // 10초마다
@Scheduled(fixedDelay = 10000, initialDelay = 2000)
@Scheduled(cron = "0 0 * * * *") // 매 정시 실행
3. cron 표현식 완전 정리
┌───────────── 초 (0-59)
│ ┌───────────── 분 (0-59)
│ │ ┌───────────── 시 (0-23)
│ │ │ ┌───────────── 일 (1-31)
│ │ │ │ ┌───────────── 월 (1-12)
│ │ │ │ │ ┌───────────── 요일 (0-6, 일=0)
│ │ │ │ │ │
│ │ │ │ │ │
* * * * * *
예시:
- 0 0/5 * * * * ->매 5분마다 실행
- 0 0 9 * * MON-FRI -> 평일 오전 9시 실행
- 0 0 2 1 * * -> 매월 1일 새벽 2시
4. @Async - 비동기 처리 핵심
✅ 기본 사용법
@EnableAsync
@Configuration
public class AsyncConfig {}
@Component
public class AsyncService {
@Async
public void asyncTask() {
// 별도 스레드에서 실행
System.out.println("비동기 작업 수행");
}
}
- 별도의 스레드에서 병렬로 실행
- 리턴값이 있는 경우 @Async + CompletableFuture<T>로 사용
⚙️ 5. 작동원리 - 프록시 기반
- @Async는 내부적으로 Spring AOP 프록시를 사용
- 호출자가 같은 클래스 내의 메서드를 직접 호출하면 비동기 작동하지 않음
- 반드시 다른 Bean이 호출해야 작동함
6. @Scheduled + @Async 병렬 실행
- 기본적으로 @Scheduled는 싱글 스레드로 작동
- 작업이 오래 걸리면 병렬 처리 불가
✅ 병렬 실행 방법
@Scheduled(fixedRate = 1000)
@Async
public void doWork() {
System.out.println(Thread.currentThread().getName());
}
⚠️ 주의
- @EnableScheduling과 @EnableAsync 모두 선언해야 함
- 비동기 실행 시 Exception은 별도 처리 필요
7. Custom Executor 설정
@Configuration
@EnableAsync
public class AsyncExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsyncExecutor-");
executor.initialize();
return executor;
}
}
- Async는 여기서 정의한 Executor를 사용함
8. 예외 처리 전략
- 비동기 작업에서 발생한 예외는 @AsyncUncaughtExceptionHandler로 처리 가능
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> {
log.error("Async Error in {}: {}", method.getName(), ex.getMessage());
};
}
9. 실무 적용 사례
- 특정 시간마다 로그 정리 or 메일 발송 (@Scheduled)
- 다량의 알림 발송 (@Async)
- 외부 API 비동기 호출 (@Async)
- 실시간 분석 작업 분산 처리
✅ 정리
| 항목 | 핵심 요약 |
| @Scheduled | 주기적 실행 (기본은 싱글 스레드) |
| @Async | 별도 스레드에서 비동기 실행 |
| 병렬 처리 | @Scheduled + @Async 조합 필수 |
| 실무 적용 | 대용량 처리, 외부 연동, 백그라운드 작업 |
| 확장 방법 | Custom Executor 설정, 예외 핸들러 구성 |
🔜 다음 포스팅 예고
Spring Batch 핵심 개념 완전 정복 - Step, Job, Reader/Processor/Writer 구조부터 실무 적용까지
'Framework > Spring' 카테고리의 다른 글
| Spring MVC 요청 처리 흐름 완전 정복 - DispatcherServlet부터 Controller까지 (0) | 2025.07.02 |
|---|---|
| Spring Boot 자동 설정 원리 완전 정복 - @EnableAutoConfiguration 내부에서 벌어지는 일 (0) | 2025.06.25 |
| 🔐 Spring Security & JWT 인증 흐름 완전 정복 - 로그인 인증부터 토큰 발급, 필터 구조 (0) | 2025.06.24 |
| ⚠️Spring 예외 처리 완전 정복 - @ControllerAdvice, @ExceptionHandler, 그리고 실무 예외 전략 (0) | 2025.06.18 |
| 🔄 Spring의 @Transactional 완전 정복 - 개념, 원리, 동작 방식, 트러블 슈팅까지 (0) | 2025.06.11 |