-
비동기 처리로 90% 이상의 성능 향상하기프로젝트 2024. 12. 3. 10:56
서비스 개발을 하다 보면, 사용자에게 더 빠르고 효율적인 응답을 제공하는 것은 가장 중요한 과제 중 하나입니다. 이번 포스팅에서는 제가 진행한 HospitalInfoService와 MapService의 성능 최적화 사례를 공유합니다. 동기 처리 방식에서 발생하던 병목을 비동기 처리로 개선하여 전체 응답 시간을 약 26,846ms에서 2,679ms로 단축한 이야기를 다룹니다.
1. 성능 저하의 원인 분석
최적화 작업에 앞서 먼저 성능 저하의 원인을 분석했습니다. 기존 시스템에서는 Kakao API 호출을 포함한 여러 작업이 동기적으로 처리되고 있었습니다. 이러한 방식은 각 병원에 대한 지도 정보를 요청할 때 모든 요청이 차례로 진행되었고, 결과적으로 응답 시간이 매우 길어졌습니다. 특히 병원이 여러 개일 경우 각 API 호출이 직렬로 처리되어, 전체 응답 시간이 기하급수적으로 증가하였습니다.
2. 주요 최적화 내용
성능을 대폭 향상시키기 위해 아래와 같은 비동기 처리와 캐싱 전략을 도입하였습니다.
2.1. 비동기 처리 도입 (CompletableFuture 활용)
먼저, Kakao API 호출을 비동기 처리로 변경하였습니다. MapService의 getMapInfo 메서드를 비동기 메서드 (getMapInfoAsync)로 수정하여, 여러 병원의 지도 정보를 병렬로 요청할 수 있도록 구현했습니다. 이를 통해 각 호출이 독립적으로 이루어져 전체 응답 시간을 크게 줄일 수 있었습니다.
아래는 변경된 코드 스니펫입니다:
@Async("taskExecutor") @Transactional(readOnly = true) public CompletableFuture<MapInfoResponseDto> getMapInfoAsync(double originLat, double originLon, double destLat, double destLon) { try { MapInfoResponseDto result = getMapInfo(originLat, originLon, destLat, destLon); log.info("Fetched map info asynchronously for origin: {},{} and dest: {},{}", originLat, originLon, destLat, destLon); return CompletableFuture.completedFuture(result); } catch (Exception e) { log.error("Error fetching map info for origin: {},{} and dest: {},{}", originLat, originLon, destLat, destLon, e); return CompletableFuture.completedFuture(null); } }
이 코드를 통해 HospitalInfoService의 getRangeAllHospital 메서드에서도 각 병원에 대한 지도 정보 요청을 비동기적으로 처리할 수 있게 되어, 실행 시간이 크게 개선되었습니다.
2. 성능 개선 결과
이번 최적화 작업을 통해 다음과 같은 놀라운 성능 향상을 이루었습니다:
- 기존 실행 시간: 약 26,846ms
- 최적화 후 실행 시간: 약 2,679ms
- 개선 비율: 약 90% 이상의 성능 향상
이렇게 비동기 처리와 캐싱 전략을 통해 전체 응답 시간을 대폭 줄여, 사용자 경험을 크게 개선할 수 있었습니다. 이 작업은 서비스의 가용성과 반응성을 높여주는 중요한 변곡점이 되었습니다.
3. 결론 및 교훈
이번 작업에서 중요한 교훈은 다음과 같습니다:
- 비동기 처리의 강력함: 많은 외부 API 호출이 필요한 서비스에서는 비동기 처리가 필수적입니다. CompletableFuture를 활용한 비동기 처리는 개발자가 다루기 쉽고, 효과적입니다.
- 병렬 처리와 캐싱의 조합: 병렬 처리와 적절한 캐싱 전략의 조합은 성능을 극대화할 수 있는 강력한 방법입니다.
이 최적화 과정은 단순히 성능을 높이는 것을 넘어, 사용자가 더 만족할 수 있는 서비스를 제공하는 데 큰 도움이 되었습니다. 앞으로도 지속적인 성능 모니터링과 최적화를 통해 더욱 나은 사용자 경험을 제공하려 합니다.🚀
'프로젝트' 카테고리의 다른 글
Java 거리 계산 최적화: Haversine 공식에서 SQL 공간 쿼리로 (0) 2024.12.03 Mockito 테스트에서 @Value 주입 문제 해결하기: ReflectionTestUtils 사용기 (0) 2024.12.03 EFK를 이용한 Kubernetes 클러스터에서 백엔드 로그 수집하기 (0) 2024.12.03 [Spring AI] 생성형 AI의 비용, 성능 최적화 (0) 2024.09.03 초보자 안내 서비스 : Vector Databases 선정 (0) 2024.06.27