코드 저장소.

첨부파일에 관련된 로직의 고찰 본문

포폴/일정관리앱

첨부파일에 관련된 로직의 고찰

slown 2025. 3. 23. 12:12

목차

1. 현재 코드의 문제

2. 문제의 대안

 

1. 현재 코드의 문제

현재 일정관리 프로젝트를 진행을 하면서 일정을 등록시 첨부파일을 등록을 하는 기능을 만들었다. 현재의 업로드 방식은 업로드후 로컬에 저장을 하는 방식이었다. 아래는 내가 작성한 첨부파일에 관련된 코드의 일부분이다.

 

// 기존 방식: 로컬 경로에 파일 저장 + 썸네일 생성 + AttachModel 생성까지 모두 한 메서드에서 처리
public static List<AttachModel> uploadMultipleFiles(...) {
    // 1. 디렉토리 생성
    // 2. 확장자 판별
    // 3. 썸네일 생성
    // 4. 파일 저장 및 AttachModel 구성
}

 

이 방식에는 여러가지의 문제점이 있는데 문제점은 아래와 같습니다.

 

1-1. 서버 자원(I/O) 부담 및 확장성 문제

첨부파일 업로드는 서버 측에서 바이너리 데이터를 처리해야 하며, 이 과정에서 두 가지 주요 리소스를 사용하게 됩니다.

  • 디스크 I/O: 파일을 저장하거나 삭제할 때, 파일 시스템 접근이 병목 지점이 되어 처리 속도에 영향을 줍니다.
  • 메모리 사용량 증가: Spring의 MultipartFile 처리는 기본적으로 업로드된 파일을 메모리에 우선 로딩한 뒤, 지정된 임계치를 초과할 경우에만 디스크로 flush됩니다.
  • 따라서 대용량 파일을 다수 업로드하거나, 동시 업로드 요청이 많을 경우, JVM 힙 메모리에 수십~수백MB가 일시적으로 적재되며, 이는 GC지연이나 OutOfMemoryError로 이어질 수 있습니다.

결과적으로 서버의 전체적인 처리 속도가 저하되며, 응답 지연, 스레드 블로킹, 시스템 불안정 등의 문제가 발생할 수 있습니다.

 

1-2. 보안 취약점

  • 업로드 경로 계산이 부정확할 경우, 루트 디렉토리 접근 등으로 시스템 파일을 덮어쓸 위험이 있습니다.
  • 파일 URL(/uploads/filename.png)에 접근 제어가 없으면 권한 없이 접근 가능한 공개 파일이 됩니다.
  • 악의적인 사용자가 대용량 파일을 반복 업로드하면 디스크가 금세 소진됩니다.

1-3. 백업과 자동화의 어려움

  • 로컬 디스크에 저장된 파일은 백업 정책 수립이 어려우며, 배포 자동화와 연계가 힘듭니다.

1-4. CI/CD 및 Docker 환경과 충돌

  • 서버 재시작, WAR/JAR 교체 시 로컬 파일이 삭제될 수 있고 Docker 환경에서는 볼륨을 마운트하지 않으면 배포마다 첨부파일이 초기화됩니다.

2. 문제의 대안

이런 단점을 토대로 어떻게 개선을 해야될지를 고민을 하다가 AWS에서 제공하는 S3를 활용해서 PreSignedUrl을 적용하기로 했습니다. 우선 PreSignedUrl이란 다음과 같습니다.

 

PreSignedUrl?

 

AWS S3의 버킷(저장소)은 기본적으로 인증된 사용자만 접근 가능합니다. 이 점을 이용해서 특정 클라이언트가 파일을 직접 업로드하거나 다운로드해야 할 경우, 서버가 S3 권한을 직접 열어주지 않고도 임시 접근 URL을 발급할 수 있는 기능을 말합니다.

 

이 방법을 사용할 경우에는 다음과 같은 이점이 있습니다.

 

1.서버의 부담이 대폭 줄어든다.

2.보안이 강화가 된다.

3.URL의 사용기간을 제한을 해서 업로드/다운로드의 제한을 걸 수있습니다.

4.S3를 사용해서 자동백업을 할 수 있습니다.

5.서버와 분리를 했기 때문에 서버는 도메인에 집중을 할 수 있습니다.

 

이와 같은 장점을 가지고 있기에 다음 글에서는 현재 적용된 업/다운로드 로직을 PresingedUrl로 변경을 해보겠습니다.