들어가기
게시글과 이미지 등록 API 분리로 API Latency 개선기 1
들어가기게시글을 등록하는 API와 S3에 이미지를 업로드하는 API를 한 곳에서 처리하다 보면 응답 대기시간이 이미지 개수에 비례해 증가하게 됩니다. 컨트롤러에서 게시글 데이터와 이미지 데
curiosity-s.tistory.com
지난번 개선기 1에서 API 분리를 통해 응답시간을 개선해보려 했습니다.
결과는 개선되지 못했고 이번 포스팅에서 그 이유와 해결책을 찾아보도록 하겠습니다.
게시글 등록 요청 시 S3에 폴더 이동 API를 사용 중
게시글과 이미지 등록을 분리 시킬 경우 사용자가 중간에 이미지를 등록하고 중간에 게시글 작성 페이지를 이탈하는 경우 S3의 이미지 객체는 고아객체가 됩니다.
해당 문제를 해결하기 위해서 S3에 폴더를 생성해 임시 폴더와 원본 폴더를 생성하고 객체 생명주기를 설정해 임시 폴더를 주기적으로 삭제해 주었습니다.
아래 링크를 참고하시면 자세히 문제 상황을 살펴볼 수 있습니다.
S3를 이용한 사용자의 고아 이미지 처리
https://github.com/SQUAD-D/board GitHub - SQUAD-D/board Contribute to SQUAD-D/board development by creating an account on GitHub. github.com 게시판 프로젝트를 진행하면서 가장 깊은 고민이 였던 부분은 사용자의 고아 이미지
curiosity-s.tistory.com
사용자가 최종적으로 게시글 등록 요청을 보내면 서버는 S3 임시폴더에 있는 이미지를 원본 폴더로 옮기게 되는데
이 작업이 하나로 이루어져있어 성능개선이 이루어지지 못한 것입니다.
이미지가 존재하면 이미지의 정보를 RDB에 먼저 저장하고 S3에 해당 이미지들의 폴더 이동 요청을 보내게됩니다.
폴더 이동 요청을 잠시 주석처리하고 실행해보면 게시글 등록요청은 114ms 만에 완료됩니다.
S3 폴더 이동을 포함한 실행시간이 872ms에 비교해본다면 충분한 개선이 이루어졌습니다.
폴더 이동 로직을 비동기로 처리해 실제 응답 시간 개선이 이루어지는지 살펴보겠습니다
Async
폴더 이동을 비동기 처리하기 위해서 S3Service 클래스의 폴더 이동 메서드에 @Async를 선언합니다.
아무런 설정을 하지 않으면 요청마다 스레드를 생성하는 SimpleAsyncTaskExecutor를 사용하게 되는데 해당 구현체는 사용해서는 안됩니다.
SimpleAsyncTaskExecutor는 요청 마다 스레드를 생성해 비동기 작업을 처리합니다.
스레드 생성 마다 JVM은 런타임 메모리 영역 내부에 가상 머신 스택 영역을 할당합니다. JVM 또한 프로세스이기에 제한된 메모리 영역을 OS로부터 할당 받는데 무분별한 스레드 생성은 메모리 부족 현상으로 이어질 수 있습니다.
CPU 코어가 가지는 부담 또한 무시할 수 없는 오버헤드입니다.(컨텍스트 스위칭)
따라서 아래와 같이 스레드를 미리 생성해두고 사용해야합니다.
ThreadPoolExcutor 구현체를 빈으로 등록합니다.
스레드풀 구현체와 적정 스레드 풀 사이즈는 아래 포스팅을 참고해주세요.
적정 스레드 풀 크기를 고민해보자
들어가기비동기 작업을 이용하려면 스레드 풀을 이용해야 합니다. 요청마다 스레드를 생성하게 되면 생성 비용, 메모리 부족, 콘텍스트 스위칭 비용 등 여러 문제가 발생한다. 따라서 적정 수
curiosity-s.tistory.com
EC2가 t2.micro임을 고려한다면 (vCPU 1개, baseline 5%) 최대한 작게 잡아야 한다고 생각했기에 CoreSize는 1 MaxPoolSize도 1로 설정했습니다.
결과를 확인해 볼까요?
이전과 동일하게 항상 화가 나있는 루피 7마리를 준비했습니다.
위 지표는 가장 좋았던 지표이고 가장 좋지 않았던 지표는 118ms였습니다.
동기로 폴더 이동을 처리하던 방식에 비해서 86% 가량 응답시간이 개선됐습니다.
비동기 처리중 유실된 태스크의 안정적인 처리를 위해 Redis의 Stream이나 RabbitMQ를 학습해 안정성을 더해야할 것 같다는 생각도 같이 듭니다.
'Spring' 카테고리의 다른 글
게시글과 이미지 등록 API 분리로 API Latency 개선기 (3) (0) | 2024.07.06 |
---|---|
적정 스레드 풀 크기를 고민해보자 (0) | 2024.06.19 |
게시글과 이미지 등록 API 분리로 API Latency 개선기 (1) (0) | 2024.06.19 |
회원 도메인 객체 코드 개선하기 (0) | 2024.04.12 |
@Value 감옥에서 벗어나기 [@ConfigurationProperties] (0) | 2024.04.03 |