일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스프링
- 해시
- 네트워크
- 동적계획법
- programmers
- Backtracking
- 해시맵
- DynamicProgramming
- 브루트포스
- 이분탐색
- Network
- Algorithm
- DFS
- greedy
- 너비우선탐색
- switch
- boj
- 백트래킹
- 프로그래머스
- 알고리즘
- HashMap
- BFS
- 부분수열의합
- Spring
- dynamic programming
- 그리디
- 구현
- DP
- 백준
- 깊이우선탐색
- Today
- Total
옌의 로그
(충격) 지금까지 배치 서버를 써본 줄 알았는데… 아니었음 본문
1. 시작은 ‘배치 서버’라는 이름이었다
예전에 PHP로 서비스 개발을 하던 시절, 특정 시간마다 돌아가는 작업을 “batch”라고 불렀다.
보통 crontab에 등록해두고, 새벽 1시에 포인트 정산, 3시에 푸시 발송 같은 걸 처리했는데
그때는 이게 배치 작업이고, 이걸 돌리는 서버니까 배치 서버인 줄 알았다.
Spring Boot로 넘어온 이후에도 마찬가지였다.
Spring에서 @Scheduled만 붙이면 시간마다 메서드가 실행되니까 그걸 띄워두는 서버를 그냥 “배치 서버”라고 불렀다.
2. 나는 “스케줄링”만 했지, 진짜 “배치 처리”는 안 해봤다
Spring Batch를 공부하면서 놀랐다.
내가 해왔던 건 단순히 “정해진 시간에 실행하는 작업”이었고,
진짜 배치 시스템은 훨씬 더 복잡하고 구조화되어 있었다.
- 스케줄러는 “언제 실행할지”를 책임지고,
- 배치는 “어떻게 실행할지”를 책임진다.
예를 들어 내가 @Scheduled(cron = "0 0 2 * * *") 으로 포인트 정산을 돌렸을 때:
- 에러 나면? 그냥 실패
- 몇 명 처리했는지? 로그 봐야 알 수 있음
- 중간에 꺼지면? 처음부터 다시 해야 됨
- 데이터 많아지면? 성능 저하
이런 걸 하나하나 직접 해결하려고 로직을 넣었었는데,
Spring Batch는 애초에 그런 기능들을 구조화해서 제공한다는 걸 알게 되었다.
3. 진짜 배치 시스템이 필요한 순간은 언제일까?
상황 | Scheduler | Batch |
단순 반복 작업 | ✅ 적합 | ❌ 오버스펙 |
대량 데이터 처리 | ❌ 부적합 | ✅ 체크포인트, 청크 등 내장 |
실패 복구 필요 | ❌ 직접 구현 | ✅ 기본 제공 |
병렬 처리, 트랜잭션 관리 | ❌ 직접 구성 필요 | ✅ 구성 요소 분리 |
처리 이력 관리 | ❌ 로그로만 가능 | ✅ DB 테이블 자동 생성 |
4. Spring Batch의 기본 구조는 어떻게 생겼을까?
Spring Batch는 다음과 같은 구조화된 처리 단계로 구성되어 있다.
Job
- 하나의 배치 작업 단위
- 여러 Step으로 구성될 수 있음
@Bean
public Job sampleJob(JobBuilderFactory jobBuilderFactory, Step step1) {
return jobBuilderFactory.get("sampleJob")
.start(step1)
.build();
}
Step
- Job을 구성하는 실행 단위
- 각각의 Step은 Reader → Processor → Writer 흐름을 가짐
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<String> reader,
ItemProcessor<String, String> processor,
ItemWriter<String> writer) {
return stepBuilderFactory.get("step1")
.<String, String>chunk(100)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
Reader / Processor / Writer
컴포넌트역할
ItemReader | 데이터를 어디서 가져올지 (DB, CSV, API 등) |
ItemProcessor | 데이터를 어떻게 가공할지 (검증, 변환 등) |
ItemWriter | 데이터를 어디에 저장할지 (DB, 파일 등) |
예시:
@Bean
public ItemReader<String> reader() {
return new FlatFileItemReaderBuilder<String>()
.name("stringItemReader")
.resource(new ClassPathResource("input.txt"))
.lineMapper(new DefaultLineMapper<>())
.build();
}
Chunk 처리
- 데이터를 묶음 단위로 처리해서 성능을 높임
- 예: 1000건 중 100건 단위로 커밋
.chunk(100)
배치 메타 테이블
Spring Batch는 실행 이력을 자동으로 관리하기 위해 다음과 같은 테이블을 사용한다:
- BATCH_JOB_INSTANCE
- BATCH_JOB_EXECUTION
- BATCH_STEP_EXECUTION
→ 실행 이력 추적, 실패 지점 복구, 재시작 처리를 위해 반드시 필요한 구조다.
5. 난 지금까지 왜 Batch를 안 썼을까?
- 시스템 규모가 작았고
- 데이터량이 많지 않았고
- 장애 시 재처리 요구가 없었고
- cron + scheduler만으로 충분히 “돌아는 갔기 때문...”
즉, 작은 규모 + 낮은 복잡도에서는 스케줄러로 충분했던 것이다.
하지만 이제는
- 정산, 포인트, PDF 생성, 발행 등 복잡한 작업이 많아지고,
- 대용량 사용자 대상의 반복성 있는 작업도 늘어나면서,
- “진짜 배치 시스템”이 필요한 시점이 된 것 같다.
마무리하며...
나는 지금까지 배치 작업을 하고 있다고 생각했지만,
사실은 정해진 시간에 메서드를 실행하는 스케줄링 작업만 하고 있었던 것이었다.
Spring Batch는 단순한 시간 기반 실행이 아닌,
대용량 처리, 장애 복구, 실행 이력 관리, 병렬 처리까지 가능한 진짜 배치 프레임워크다.
물론 프로젝트 상황에 맞게 기술을 도입해야 하는 것이지만, 기회가 된다면 spring batch를 도입해서 사용해보고 싶다!
'스터디 > 기타' 카테고리의 다른 글
[Reactive Programming] 리액티브 프로그래밍 & 리액티브 스트림즈 (1) | 2025.08.29 |
---|---|
ENUM과 DB 매핑 전략 (feat. Enum Converter,, 코드 테이블,,) (1) | 2025.08.28 |
DDD와 Hexagonal Architecture, 상품관리 시스템에 적용해보기 (4) | 2025.08.08 |
[Linux] linux환경에서 javac로 java 컴파일하기 (0) | 2024.04.20 |
[Linux] linux환경에서 gcc로 c++ 컴파일하기 (0) | 2023.06.22 |