[Spring Boot] 다중 이미지 업로드 최적화: 413 에러 해결부터 Chunking 아키텍처까지

유자·2026년 2월 26일

multi-modal-fraud-project

목록 보기
5/16

[Troubleshooting] 413 에러와 다중 이미지 업로드(50장) 처리 전략

단일 이미지 파일을 Spring Boot에서 Python(FastAPI)으로 넘겨 JSON 응답을 받아오는 데 성공했다. 하지만 기쁨도 잠시, 실무 환경을 가정해 보니 새로운 의문이 들었다.

문제 발생: "1장은 되는데 50장이라면?"

당근마켓이나 인스타그램처럼 사용자가 한 번에 수십 장의 사진을 업로드하는 상황을 가정해 보았다. 고화질 사진 50장을 한 번에 서버로 던진다면 어떻게 될까?
테스트 결과, 컨트롤러 로직이 실행되기도 전에 톰캣(Tomcat) 단에서 에러를 뱉어내며 입구컷을 당했다.

413 Content Too Large

생각의 흐름: 원인 파악과 아키텍처 고민

1. 원인 파악: Spring Boot의 방패
스프링 부트는 악의적인 대용량 파일 공격을 막기 위해 기본 파일 업로드 제한을 아주 보수적인 '1MB'로 설정해 둔다. 요즘 스마트폰 사진 한 장이 2~3MB를 가뿐히 넘기기 때문에, 이 설정을 바꾸지 않으면 다중 업로드는커녕 단일 업로드도 실패할 수밖에 없다.

2. 꼬리를 무는 의문: 무작정 500MB로 늘리면 안전할까?
그렇다면 설정 파일에서 제한 용량을 500MB 정도로 뚫어주면 해결될까? 여기서 아키텍처에 대한 찝찝함이 밀려왔다.

  • 네트워크 불안정성: 모바일 환경에서 500MB라는 거대한 덩어리를 한 번에 보내다가 99%에서 통신이 1초라도 튀면? 처음부터 500MB를 다시 올려야 하는 최악의 사용자 경험(UX)이 발생한다.
  • AI 서버의 메모리 폭발: 파이썬(FastAPI) 서버에는 무거운 AI 모델이 올라가 있다. 이 50장 분량의 이미지가 1초 만에 메모리로 쏟아져 들어오면 서버가 견디지 못하고 뻗어버릴 확률이 높다.

해결책

위 고민들을 바탕으로, 안전하고 효율적인 다중 파일 업로드 처리 전략을 3단계로 도출했다.

Step 1. Spring Boot 설정 변경
먼저 application.properties에서 1MB 제한을 현실적으로 풀어준다. 이때 파일 1개당 크기와, 요청 1번당 총크기를 다르게 설정하는 것이 핵심이다.

# 파일 1개당 최대 크기 (단건 제한)
spring.servlet.multipart.max-file-size=10MB
# 요청 1번에 담길 수 있는 전체 크기 (총합 제한)
spring.servlet.multipart.max-request-size=500MB

Step 2. Controller 파라미터 수정
단일 객체로 받던 파라미터를 자바의 List 자료구조로 변경하여 여러 장을 줄줄이 엮어 받을 준비를 한다.

@PostMapping("/upload-images")
public String uploadImages(@RequestParam("files") List<MultipartFile> files) {
    for (MultipartFile file : files) {
        // 파일을 하나씩 꺼내어 파이썬으로 순차 전송
    }
    return "다중 업로드 성공";
}

Step 3. 궁극적인 해결책: 프론트엔드 분할 전송
가장 중요한 포인트다. 500MB를 한 번의 POST 요청으로 통째로 보내는 짓은 하지 않기로 했다. 프론트엔드 개발자와 협의하여 사용자가 50장을 고르더라도 내부적으로는 1장씩 서버로 50번 던지도록(분할 전송) 아키텍처를 잡아야 한다.

이렇게 하면 우리가 흔히 보는 "업로드 중... 10% ➔ 20% ➔ 100%" 같은 진행률 바를 구현할 수 있고, 무거운 파이썬 AI 모델도 한 번에 하나씩 차분하게 이미지를 분석할 수 있어 서버 다운의 위험을 원천 차단할 수 있다.

단순한 기능 구현을 넘어, 시스템의 안정성까지 챙기는 의미 있는 트러블슈팅이었다.

0개의 댓글