1️⃣ 전통적 Executor 모델
자바에서 우리가 쓰던 방식입니다.
ExecutorService executor = Executors.newFixedThreadPool(10); executor.submit(() -> processSettlement());
구조
- OS Thread 기반
- ThreadPool 크기 고정
- Blocking I/O면 스레드가 멈춰 있음
문제점
- 스레드 하나당 메모리 큼 (~1MB)
- 1,000개 요청 처리하려면 1,000 스레드 필요
- 대기 I/O에서 리소스 낭비
그래서 풀 크기 튜닝, 큐 사이즈 조정, Rejection 정책 고민합니다.
배치 돌릴 때:
- maxPoolSize
- queueCapacity
- CallerRunsPolicy
이런 거 고민하셨을 겁니다.
2️⃣ Virtual Thread
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); executor.submit(() -> processSettlement());
구조
- JVM이 관리하는 경량 스레드
- OS Thread에 매핑됨
- Blocking해도 다른 작업 수행 가능
차이 핵심
구분Executor (Platform Thread) Virtual Thread
| 기반 | OS Thread | JVM 관리 |
| 메모리 | 큼 | 매우 작음 |
| 생성 비용 | 비쌈 | 거의 없음 |
| 동시성 수 | 수백~수천 | 수십만 가능 |
| 코드 스타일 | 비동기/풀 튜닝 | 동기 코드 그대로 |
3️⃣ 배치/정산 관점에서 비교
예: 10,000건 정산 처리
❌ 기존 방식
- 20개 스레드 풀
- DB I/O 대기
- 처리 시간 늘어남
- 풀 크기 고민해야 함
✅ Virtual Thread
- 10,000개 작업 그냥 던짐
- 각 작업은 동기 코드
- 대기 I/O 동안 다른 작업 실행
- 풀 튜닝 거의 불필요
4️⃣ 언제 Executor가 낫나?
- CPU 연산 위주
- 병렬 계산
- ForkJoinPool 사용 시
- 라이브러리 호환성 문제 있을 때
5️⃣ 상황 적용
정산/배치 특징:
- DB I/O 많음
- 외부 API 호출 있음
- 부분환불, 멱등성 체크
이건 전형적인 I/O bound
👉 Virtual Thread 궁합 좋음
6️⃣ 코루틴이랑 뭐가 다르냐
코틀린 코루틴은:
- 완전 다른 스케줄링 모델
- suspend 기반
- non-blocking 설계 필요
Virtual Thread는:
- 기존 동기 코드 그대로 사용
- 학습 비용 거의 없음
7️⃣ 설계자 관점 핵심
- 이 작업은 CPU-bound인가?
- I/O-bound인가?
- 스레드 수를 내가 튜닝해야 하나?
- 코드 단순성이 중요한가?
LIST
'Architecture' 카테고리의 다른 글
| 헥사고날 아키텍처(Hexagonal Architecture)란 무엇인가? (0) | 2026.02.23 |
|---|---|
| 고객 행동 분석에서 시작하는 이커머스 아키텍처 설계 (0) | 2026.02.13 |
| Settlement(정산 배치) 설계 — JobRun·Item·재처리 중심 (0) | 2026.02.11 |
| Approval(상위 결재) 시스템 설계 — 상태머신·트랜잭션·멱등성 중심 (0) | 2026.02.11 |
| 정답 없는 환경에서 망하지 않는 시스템을 설계하는 법 (0) | 2026.02.10 |
