[SpringBoot] ⛔ Error - AWS Elastic Beanstalk 413 Request Entity Too Large

Ogu·2024년 1월 30일
4
post-thumbnail

문제 상황

postMan으로 pdf를 업로드 할 때 image확장자가 아니어서 예외로 걸러지는지 확인하려고 요청을 보냈는데, ⛔413 Request Entity Too Large 오류가 터졌습니다.
yml에서 multipart size도 설정했었는데 무엇이 문제인지 한참 찾고, 그 해결 방안도 한참 헤맸습니다..

문제 원인

기본적으로 NGINX서버의 문제였습니다.
앞선 글에서 살펴봤듯이, ElasticBeanstalk은 default로 Reverse proxy로 nginx를 사용해서 기본적으로 깔려있는 Nginx의 설정때문이었습니다.
NGINX의 default 설정은 파일 업로드 시 1MB로 제한되어서 요청 크기가 구성된 값을 초과하면 413 Request Entity Too Large 오류가 반환됩니다.
이 설정은 Nginx의 client_max_body_size 로 할 수 있는데요, 원래는 client가 너무 큰 사이즈의 request 를 보내지 못하도록 request의 Content-Length 헤더값이 client_max_body_size에 설정된 값을 넘을 수 없도록 제한하는 용도라고 합니다. 따라서, 1MB보다 큰 파일을 업로드하려면 NGINX 구성 파일에서 client_max_body_size 명령을 구성해야 합니다.
AWS Elastic Beanstalk 413 Request Entity Too Large 오류 해결

해결 방법

Elastic Beanstalk을 쓰지 않는 환경이었다면, 직접 nginx 설정을 건드렸겠지만,
저는 Elastic Beanstalk의 사용 이유인 비즈니스 로직 의외의 인프라에 신경을 쓰지 않아도 되는 목적을 위반하기 때문에 직접 ec2의 nginx 설정을 건드리는 것은 올바르지 않다고 생각했고,
다른 방법을 찾아야 했습니다.

ElasticBeanstalk에서도 이에 따른 Linux 플랫폼 확장 방법에 대하여 공식 문서를 제공하고 있었습니다.
즉, ElasticBeanstalk에 업로드(배포)되는 어플리케이션 패키지 내에서 설정하는 방법입니다.

해당 설정은 Amazon Linux 2이상 또는 Amazon Linux 2023 플랫폼에서만 적용되니 그 이하 버전은
.ebextensions 하위에 설정하는 다른 설정문서를 참고하세요!

기본 nginx 구성에 확장하는 설정 추가

해당 문서를 보면 기본 nignx 구성에 확장을 위해선 다음과 같이 추가하라고 나와있습니다.

아래에서 제공하는 응용 예시를 보면 다음과 같은데요,

저는 build 이후 .jar 파일 하나만 업로드하고 배포하는 상황이었습니다.

따라서 프로젝트 루트 바로 아래에 .platform 폴더를 만들어 다음과 같이 두 개의 설정 파일을 작성했습니다.
(.conf 확장자 외에 파일 이름은 아무렇게나 지어도 상관 없습니다. ex) client_max_body_size.conf , proxy.conf, myconf.conf 등)

.platform/nginx/conf.d/myconf.conf

client_max_body_size 50M;

.platform/00_nginx.config

container_commands:
    00_reload_nginx:
        command: "service nginx reload"

.jar파일과 .platform 폴더를 함께 압축하여 zip 자체를 업로드

설정 이후 빌드 후 .jar 파일을 배포해도 똑같이 오류가 사라지지 않았는데, 그 이유는 Spring Boot는 기본적으로 빌드된 JAR 파일에 필요한 리소스만을 포함시키기 때문에 해당 설정들이 포함되지 않습니다.

따라서 Elastic Beanstalk에 .platform/nginx/conf.d/client_max_body_size.conf 설정 파일을 포함시키려면 빌드된 JAR 파일 이외에 별도로 .platform 디렉토리를 포함하는 작업을 해주어야 합니다.

Mavben에서는 maven-resources-plugin이나 maven-assembly-plugin과 같은 플러그인을 사용하여 해당 디렉토리를 별도로 포함시킬 수 있지만,

저는 zip파일 내에 jar파일과 해당 .platform 폴더 자체를 포함해서 업로드 했습니다.
(.platform은 업로드 시 nginx 내에서 최상위에 위치만 하면 되는 것이기 때문에 꼭 springboot 안에서 설정해 줄 필요는 없을 것 같기도 합니다.)

따라서 다음과 같이 아무런 폴더를 만들어 .platform 폴더를 복사하여 넣고, build한 jar 파일도 포함시킨 후, zip으로 만들었습니다.

그리고 ElasticBeansalk에 해당 zip 자체를 업로드 했습니다.

드디어 정상적으로 Client의 Request 용량이 확장되어 정상적인 Error Log를 볼 수 있어 졌습니다.

저의 경우에는 이미지는 글 중간에 넣자마자 서버에 업로드 되게 하여 imgURL을 바로 받아오도록 했습니다. (Quill 에디터에서 default는 base64 형식으로 이미지를 넣게 되는데, base64는 매우 긴 문자열 몇천자로 나타남)

따라서 해당 API는 이미지만 controll하기 위해 이외 확장자 file일 경우 Error 가 뜨도록 따로 설정해줬습니다.

이미지가 아닌 pdf와 같은 File 업로드 처리도 필요했기에, Client Request 용량 확장은 꼭 필요했습니다.
이제는 기타 확장자의 file들을 업로드하는 API를 따로 구현해야 할 일이 남았습니다.

또다른 오류

이번에는 react에서 해당 이미지 업로드 api로 파일을 보내는 요청을 하니 아래와 같은 오류가 떴습니다.

일반적으로 이러한 경고는 클라이언트가 매우 큰 데이터를 POST 요청으로 보내고 있을 때 발생한다고 합니다. Nginx는 클라이언트 요청 바디가 설정되어있는 client_body_buffer_size 버퍼 사이즈보다 크면 임시 파일에 저장한다고 합니다.

2024/01/31 05:06:15 [warn] 369274#369274: *587 a client request body is buffered to a temporary file /var/lib/nginx/tmp/client_body/0000000034, client: 172.31.17.231, server: , request: "POST /api/images HTTP/1.1", host: ~~~

따라서 위와 다르게 client_body_buffer_size 50M;를 설정해주어야 하는데요

오늘의 교훈

블로그나 기타 국내외 개발 커뮤니티도 좋지만 그것만으로 잘 안될땐 공식문서를 보자!
그러므로 대학생활 이후 까먹은 영어들 다 되찾아오자! (너 영어 엄청 좋아했잖아..) 영어공부!!!!

참고

profile
私はゲームと日本が好きなBackend Developer志望生のOguです🐤🐤

3개의 댓글

comment-user-thumbnail
2024년 1월 30일
2개의 답글