
핵심요약
이 글은 Java 8 CompletableFuture를 활용하여 데이터 마이그레이션 중 발생한 성능 저하 및 데이터 비교 문제를 비동기 처리로 해결한 경험과 그 과정에서 학습한 핵심 개념들을 공유합니다.
Java CompletableFuture를 활용한 비동기 처리 개선
이 글은 데이터베이스 이관 과정에서 발생한 순차적 로직 실행으로 인한 성능 저하 및 데이터 불일치 문제를 해결하기 위해 Java CompletableFuture를 활용한 비동기 처리 도입 과정을 상세히 다룹니다.
CompletableFuture 기본 개념 및 인스턴스 생성
- 비동기 처리의 필요성: 기존 동기 처리의 성능 문제와 1초 차이로 인한 결과 비교 실패 문제를 해결하기 위해 비동기 도입.
- CompletableFuture 소개: Java 8에 도입된 클래스로, 기존
Future인터페이스의 연산 결합 및 예외 처리의 어려움을 개선. - 인스턴스 생성:
CompletableFuture.supplyAsync()정적 메서드를 통해 비동기 연산을 시작하며,Supplier를 인수로 받아ForkJoinPool.commonPool()에서 작업을 수행.
CompletableFuture의 핵심 연산 메서드 활용
- 순차적 연산 처리: 이전 단계의 결과를 다음 연산으로 전달하는
thenApply()(Function 인수로 결과 반환),thenAccept()(Consumer 인수로CompletableFuture<Void>반환),thenRun()(Runnable 인수로CompletableFuture<Void>반환) 메서드를 통해 비동기 작업을 순차적으로 연결. - 연산 결합:
thenCompose()(이전CompletableFuture결과를 다음CompletableFuture의 입력으로 사용)와thenCombine()(두 개의 독립적인Future결과를BiFunction으로 결합)를 통해 복잡한 비동기 흐름을 구성.thenAcceptBoth()는 결과값이 필요 없을 때 유사한 기능 제공. - thenApply vs thenCompose:
thenApply()는 값에 대한 변환을,thenCompose()는 Future 체이닝을 목적으로 사용하며, 최종 결과만 필요할 경우thenCompose()가 더 적합.
고급 비동기 처리 및 예외/타임아웃 관리
- 병렬 처리:
CompletableFuture.allOf()를 사용하여 여러Future를 병렬로 실행하고 모든 작업 완료를 대기. 단, 결과 결합은 직접 처리해야 하며,join()메서드를 활용할 수 있지만 미확인 예외 발생 가능성을 고려해야 함. - 비동기 메서드 (
Async접미사):supplyAsync(),thenApplyAsync()등Async접미사가 붙은 메서드는 다른 스레드를 사용하여 비동기 연산을 수행하며,Executor를 직접 제공하거나 기본ForkJoinPool을 사용. - 예외 처리:
handle()메서드를 통해 성공 결과와 발생 예외를 모두 처리할 수 있으며,completeExceptionally()메서드로 비정상적인 완료를 강제하고 예외를 지정할 수 있음. - 타임아웃 설정: Java 8의
get(timeout, unit)메서드 외에, Java 9부터는orTimeout()(지정 시간 초과 시ExecutionException발생) 및completeOnTimeout()(지정 시간 초과 시 기본값으로 완료) 메서드가 추가되어 유연한 타임아웃 처리 가능.
11번가