[문제해결] nginx body 값 최대 사이즈
0. 문제상황
현재 사이드프로젝트에서 네이버폼과 같이 지원서폼을 자체적으로 만들어서 사용하고 있는데요. 파일 첨부 기능도 포함되어있습니다. 그런데 최근에 파일을 request body 값으로 MultipartFile 을 보낼 때 CORS 오류와 함께 413 Payload Too Large
가 발생했습니다. 413 에러는 처음이라 조금 당황했습니다.
1mb 이상인 파일을 보내면 해당 에러가 발생했습니다.
0.1 문제 원인
원인은 간단하게 “http 요청 크기가 커서” 입니다. 처음에는 spring 의 multipart max-file-size 의 설정이 잘못되었다고 생각했는데 해당 설정은 “10mb” 로 잘 되어있었습니다.
그래서 api_log 를 분석하려고 DB 를 봤는데요. 이상하게 api_log 가 없었습니다. 그래서 저는 처음에 프론트페이지에서 1mb 가 넘는 파일을 처리하지 못했다고 생각했습니다. api_log 에 찍히지 않았으니까요. 하지만 프론트측에서는 1mb 크기에 대해 딱히 제한을 두지 않았고, 개발자 도구에서 확인을 해도 서버 요청이 실패하고 있었습니다.
그래서 저는 프론트보다는 뒷단이지만 서버보다는 앞단은 nginx 문제라고 생각해서 구글링을 해보니 nginx 의 기본 최대 요청크기가 1mb 인 것을 찾았습니다.
1. 문제 해결
방법은 두가지입니다.
- s3 에 presigned-url 로 업로드하고 url 만 저장
- nginx 의 설정값을 10mb (적당히 크게) 로 늘리기
저는 2번 방법을 택했고 그 이유를 설명드리겠습니다.
1.1 nginx 설정값 변경
nginx 의 http { }
안에 client_max_body_size 속성을 추가하거나 변경해야 합니다. 저는 elasticbeanstalk 을 사용하고 있으니 아래와 같은 디렉토리 구조에 myconf.conf 를 넣습니다.
|-- .platform
| `-- nginx
| `-- conf.d
| `-- myconf.conf
`-- 프로젝트 파일들
myconf.conf 는 아래와 같습니다.
client_max_body_size 10M;
이렇게 설정하고 jar 파일에 넣으면 elasticbeanstalk 에서 해당 파일을 읽어서 /etc/nginx/
에 conf.d/myconf.conf
를 넣습니다. nginx 의 설정은 /etc/nginx/nginx.conf
에 있는데요. 해당 설정의 http {} 를 보면 include conf.d/*.conf;
라고 되어있습니다. conf.d 에 있는 conf 파일을 읽어서 설정에 넣는다는 의미입니다.
어쨌든 저는 위 방법으로 nginx 가 받을 수 있는 max 값을 늘려서 해결했습니다.
1.2 설정값 변경으로 택한 이유
첫번째는 빠르게 해결하기 위해서입니다. 지금 당장 운영되고 있는 서비스인데 코드 변경없이 해결하려면 nginx 설정을 변경하는 게 간편했습니다. 파일 크기가 커지면 클라이언트도 대기시간이 길어지고 서버 부하도 있겠지만 지금은 그걸 고민할 부하량은 아니니까요.
두번째로 presigned-url 으로 파일을 받았을 때 두가지 에러 사항이 있을 수 있습니다.
- 저장된 파일의 url(s3://somewhere) 을 받았지만 오류로 인해 해당 위치에 파일이 없는 경우
- 오류로 인해 파일의 url 을 받지 못했지만 해당 위치에 파일이 저장된 경우
2번의 경우는 몇mb 정도의 불필요 파일이 저장되어도 무시할만하니 괜찮지만 1번은 문제가 큽니다. 따라서 해당 파일이 실제로 있는지도 확인해주는 단계가 필요해서 꽤나 복잡합니다. 여기에 대해서는 aws multipart upload 를 사용해서 해결할 수 있는데 다음에 개선할 때 천천히 적용해볼 생각입니다. 해당 내용은 이전에 생각해본거기도 하구요. 이전에 고민한 글
댓글남기기