체험일지 이미지 등록 성능 개선 – Presigned URL (2)

·2025년 5월 20일
0
post-thumbnail

앞선 글에서는 Multipart 방식과 Stream 방식의 한계를 정리하고, 그 대안으로 Presigned URL 방식을 소개했습니다.

이번 글에서는 Presigned URL이 어떻게 동작하는지, 그리고 프로젝트에 어떻게 적용했는지 소개하겠습니다.


AWS S3 Presigned URL

앞서 살펴본 Multipart 방식과 Stream 방식 모두 공통적으로 서버가 직접 업로드를 처리해야 하기 때문에, 서버 자원 사용량 증가와 요청 처리 병목이라는 구조적인 한계를 가지고 있습니다.

이러한 문제를 해결하기 위해, 클라이언트가 직접 S3에 이미지를 업로드할 수 있도록 하는 AWS S3 Presigned URL 방식이 있습니다.

흐름
1. 클라이언트가 서버에 업로드할 이미지의 메타데이터(파일 이름, 크기 등)를 요청으로 전달
2. 서버는 해당 정보를 기반으로 S3에 유효 기간이 포함된 Presigned URL을 생성
3. 서버는 생성된 Presigned URL을 클라이언트에 응답으로 반환
4. 클라이언트는 해당 URL을 사용해 S3에 이미지를 직접 업로드 (PUT 요청)

  • S3는 objectKey(저장 경로)가 중복되면 기존 객체가 덮어쓰기 되는 특성이 있습니다. 그러므로 obejctKey 생성 할 땐, UUID 등을 활용하여 고유한 경로를 생성해야합니다.
  • 또한, 클라이언트에서 직접 S3에 접근해 파일을 업로드하기 때문에 보안에 취약할 수 있습니다. 이를 방지하기 위해, Presigned URL의 유효 시간을 짧게(예: 3분) 설정하는 것이 좋습니다.

  • 응답 받은 URL로 PUT요청을 보냅니다.


장단점

장점

- 서버 자원 절약

서버가 파일을 직접 수신하지 않고 URL을 생성해서 발급만 해주기 때문에, CPU 및 메모리 사용량을 최소화할 수 있습니다. 특히 이미지, 동영상과 같이 대용량 파일 업로드 시 효과적입니다.

- 업로드 속도 향상

클라이언트가 S3에 직접 PUT 요청을 보내므로 서버를 거치지 않아 네트워크 병목이 줄고, 업로드 속도가 향상됩니다.

※ 아래는 1GB 4개의 파일을 동일한 네트워크, 동일한 테스트 환경(k6 기반)에서 측정한 결과입니다.

✅ 단일 1GB 파일 업로드 성능 비교

업로드 방식업로드 시간비고
Multipart 업로드59.0초서버 메모리·디스크 점유 높음
Stream 업로드38.8초커넥션 수 증가 시 병목 가능성 있음
Presigned URL19.2초서버 부하 없음, 가장 빠름

iteration_duration.avg 기준으로 작성

단점

- 업로드 성공 여부 추적 어려움

파일 업로드가 클라이언트 → S3로 직접 이루어지기 때문에, 서버는 업로드 완료 여부를 즉시 알 수 없습니다. 따라서 업로드 후 클라이언트가 별도의 완료 알림 API를 호출하거나, S3의 트리거를 통해 추가 작업(DB 저장, 썸네일 생성 등)을 해야합니다.

- S3에 대한 의존도 증가

Presigned URL 방식은 S3에 직접 접근하기 때문에, S3 사용을 전제로 한 아키텍처가 됩니다. 향후 스토리지 변경이 필요할 경우 유연성이 낮아질 수 있습니다.

- CORS 설정 필요

클라이언트가 브라우저에서 S3에 직접 PUT 요청을 보내는 구조이므로, S3 버킷에 CORS 정책을 설정하지 않으면 요청이 차단됩니다. 보안상 허용 도메인을 제한하여 CORS 설정을 구성해야 합니다.


왜 Presigned URL 방식을 선택했는가?

각 업로드 방식의 장단점을 비교한 끝에, 최종적으로 Presigned URL 방식을 선택한 이유는 다음과 같습니다.

  • MultipartFile 방식은 서버가 파일을 먼저 수신한 뒤 S3로 전송해야 하므로, CPU·메모리·디스크 점유율이 모두 높았습니다. 실제 테스트에서도 디스크 사용량이 가장 높았으며, 병렬 업로드 시 병목 현상이 쉽게 발생했습니다.

  • Stream 방식은 디스크 사용은 비교적 적었지만, 파일 업로드 중 서버가 연결을 지속적으로 유지해야 하므로 커넥션 수가 많아질수록 병목이나 오류 가능성이 커졌습니다.

  • 반면, Presigned URL 방식은 클라이언트가 직접 S3로 업로드하기 때문에, 서버 리소스를 거의 사용하지 않고, 업로드 속도 또한 가장 빠른 결과를 보여주었습니다.

또한, 현재 시스템은 AWS S3 기반으로 구축되어 있으며, 다른 스토리지로 이전할 계획도 없기 때문에 Presigned URL 방식이 장기적인 관점에서도 가장 적합하다고 판단했습니다.

다만, 이는 현재 프로젝트의 상황과 요구사항에 맞춘 선택이며,
업로드 방식은 절대적인 정답이 아니라, 프로젝트의 규모, 트래픽, 인프라 구성, 보안 요구사항 등을 종합적으로 고려해 결정해야 한다고 생각합니다.


✅ 최종 체험일지 API 성능 테스트 결과

항목Multipart 방식Presigned URL 방식개선 효과
평균 응답 시간1.69초1.33초20% 단축
CPU 최대 사용률21%4%81% 감소
테스트 조건VU 1, 10회 반복, 10MB 이미지 5장동일-
비고서버 직접 파일 처리클라이언트 업로드 + 서버 확인리소스 효율성 및 확장성 우수

최소한의 테스트 환경에서도 Presigned URL 방식은 응답 속도와 서버 리소스 사용 면에서 유의미한 개선을 확인할 수 있었습니다.
특히 동시 사용자 증가 또는 파일 개수 확장 시, 이점은 더욱 커질 것으로 생각합니다.


다음 포스트

현재 프로젝트에서는 이미지를 업로드한 뒤, 최종적으로 체험일지 작성 API를 호출하여 모든 프로세스를 마무리합니다.
하지만 이미지를 업로드만 하고 체험일지 작성을 완료하지 않는 경우,
S3에는 사용되지 않는 이미지가 남게 되고 이는 불필요한 스토리지 비용 증가로 이어질 수 있습니다.

👉 다음 포스트에서는 이러한 문제를 방지하기 위한 “Presigned URL LifeCycle 설계 및 자동 정리 방식”에 대해 소개하겠습니다.

📚 Reference

0개의 댓글