개발자

Nginx, Express 연결 후 프론트에서 이미지 파일 전송시 408 Error

2024년 02월 10일조회 284

안녕하세요. 혼자 해보던 도중 도저히 해결이 되지 않아 문의드립니다. - 서버 설계 - 현재 저는 Express앱을 AWS EC2 인스턴스에 NGINX를 설치한 후 proxy_pass에 express앱이 구동중인 port를 연결하여 사용하고 있습니다. 이 과정에서 ALB를 통해 ACM을 연동하여 HTTPS 프로토콜이 사용가능하게 설정까지 하였습니다. 이미지 파일업로드는 multer-s3를 이용해 s3버킷과 연결하여 업로드 되는 방식입니다. - 문제상황 - 로그인과 기본적인 CRUD는 문제없이 되는데, 프론트에서 이미지 파일(multipart/form-data)을 서버로 전송하면 504 오류가 출력됩니다. 1. nginx의 access.log에는 해당 uri의 상태코드가 408이라 출력됩니다. 2. nginx의 error.log에는 readv() failed (104: Connection reset by peer) while reading upstream가 출력됩니다. 3. 개발자도구의 console창에 'server의 이미지 업로드 uri' from origin '프론트 도메인'이 has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 이라 출력됩니다. 위 오류를 해결해보기 위해 시도해본 것은 아래와 같습니다 1. NGINX의 proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout, send_timeout을 600으로 설정, client_max_body_size를 500M으로 설정 2. ALB의 유휴제한시간 600 설정 3. Express 앱에 app.set('trust proxy', true); 추가 4. Express-session에 app.use(session({proxy:true})) 추가 5. body-parser에 app.use(bodyParser.json({limit: '1000mb'})); 추가 및 app.use(bodyParser.urlencoded({limit: '1000mb', extended: true})); 추가 6. 업로드되는 uri의 미들웨어에 (req, res, next) => { req.setTimeout(1000000); next(); } 추가 7. upload.single()미들웨어를 주석처리 후 req.file 출력 시도 아직도 해결을 하지 못하였습니다 ㅜㅜ 연휴임에도 도와주시면 너무 감사하겠습니다..

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 2

프레드윰님의 프로필 사진

Access-Control-Allow-Origin 는 허용 하셨나요? app.use(cors({ origin: true, credentials: true }));

profile picture

익명

작성자

2024년 02월 13일

Origin에 프론트 주소 넣어놨습니다..! 이미지 업로드 api 빼고 다른부분들은 cors에러 안나요.!

백승훈님의 프로필 사진

CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 에러가 발생한다면 데이터 (이미지 등)이 백엔드에 아예 전달이 안되는 상태입니다. 프론트의 코드나 업로드 방식을 먼저 파악해보시는게 좋을 것 같습니다. (예를 들어 이미지가 아닌 json으로 넣은게 아닌지, 업로드 방식이 옳바른지, 바라보는 주소가 맞는지 등등) Postman 등을 통해 먼저 서버에 다이랙트로 이미지를 찔러보시고 해당기능이 정상 동작하는지 먼저 확인해보시기 바랍니다. 만약 정상 작동한다면 프론트의 코드를 수정해야 하며 정상적으로 들어가지 않는다면 서버의 문제라고 가정하시면 됩니다. 작성하신 내용들이 전부 서버 및 인프라단에서 수정하신 것 같은데 먼저 어느 쪽에서 문제인지 파악하는게 필요할 것 같습니다. 먼저 다음 방법을 시도해보시기 바랍니다. 1. CORS 문제 해결 (하단 코드부분) 2. NGINX 설정 최적화 NGINX에서 큰 파일 업로드를 처리하기 위해 client_max_body_size를 조정하셨으나, proxy_buffer_size, proxy_buffers, proxy_busy_buffers_size 등의 추가적인 버퍼 사이즈 조정이 필요할 수 있습니다. 3. NGINX 로그 문제 해결 408 Request Timeout과 Connection reset by peer 오류는 클라이언트에서 서버로의 요청이 너무 오래 걸리거나 연결이 중간에 끊어져 발생합니다. 이는 파일 업로드 시간이 길거나 네트워크 불안정성 때문일 수 있습니다. proxy_read_timeout 설정을 조정하셨지만, NGINX와 Express 앱 간의 연결이 불안정한 것으로 보입니다. NGINX와 Express 앱 간의 네트워크 연결을 검토하고, 필요하다면 NGINX의 keepalive 설정을 조정해 보십시오. 4. 파일 업로드 미들웨어 검토 multer-s3를 사용하여 파일을 업로드할 때, 미들웨어 설정이 올바르게 구성되었는지 확인합니다. upload.single() 미들웨어를 주석 처리하셨을 때 문제가 해결되지 않았다면, 문제는 multer 설정보다는 앞서 언급된 CORS, NGINX 설정 또는 AWS 구성에 더 깊이 관련되어 있을 수 있습니다. 추가 조치 사항 AWS Security Group과 Network ACLs 설정을 확인하여 EC2 인스턴스로의 인바운드 및 아웃바운드 트래픽이 올바르게 허용되고 있는지 검토합니다. ALB 로그를 활성화하여 요청이 ALB를 통과하여 EC2 인스턴스까지 도달하는지 확인합니다.

1app.use(cors({
2  origin: '프론트엔드 도메인', // 프론트엔드 도메인을 정확히 명시하거나 '*'로 모든 도메인 허용
3  credentials: true, // 쿠키를 포함한 요청을 허용
4  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], // 메소드에 OPTIONS 추가
5}));
profile picture

익명

작성자

2024년 02월 13일

안녕하세요! 먼저 답변 달아주셔서 너무 감사드립니다. 1번 방안으로 추가를 해봤는데 해결이 아직 안되었고, POSTMAN으로 테스트를 해보면 111KB의 작은 이미지를 업로드하는데도 10분이상 걸리고 결국 끝내 504ERROR가 리턴됩니다ㅜㅜ... 어떤게 문제일까요...

profile picture

익명

작성자

2024년 02월 13일

코드 자체를 app.post('이미지 업로드 경로', async (req, res) => { return res.status(200) }); 이렇게 수정했는데 504가 반환돼요..ㅠㅠ

백승훈님의 프로필 사진

백승훈

프론트 엔드 개발자 (FE)2024년 02월 13일

아마 multer와 백엔드가 제대로 연결되지 않은 듯 합니다. Aws의 설정부분이나 Nginx를 수정해야 할 듯 한대.. 해당부분은 저도 공부한 지 얼마 되지않아 확실한 방법을 모르겠내요😂 업로드한 파일이 저장되는 공간등도 정확히 지정되어 있는지 확인이 필요할 것 같습니다. 단편적인 코드로는 확인이 힘드내요

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 02월 10일

이 경우는 매우 복잡한 상황으로 보입니다. 하지만 대부분의 경우 408 에러 상태 코드는 클라이양트가 서버가 요청을 완료하는데 필요한 시간보다 더 오래 기다렸음을 나타냅니다. 파일 업로드가 실패하면 일반적으로 두 가지 주요 원인이 있습니다. 1. 파일 자체에 문제가 있거나, 2. 업로드하는 동안 연결이 끊어져서입니다. 공유해주신 정보를 바탕으로 판단했을 때, 이 문제는 네트워크 통신과 관련된 것 같습니다. 'Connection reset by peer' 오류 메시지는 다른 쪽편에서 연결을 강제 종료했음을 나타내며, 일반적으로 클라이언트나 중간의 프록시 서버와 같은 다른 네트워크 요소에서 발생합니다. 확인해보셔야 할 사항들은 다음과 같습니다: 1. 파일 크기 제한: 약간의 용량 초과로 인해 요청이 거부되는 경우도 있습니다. `client_max_body_size`를 증가시켜봤으니 이 부분은 문제가 없어 보입니다. 2. AWS ALB Inactivity timeout: 이 값을 600으로 설정하셨으니 별도의 문제는 없어 보입니다. 3. AWS ALB 이외의 인프라에서 timeout이 발생하고 있는가: ELB를 사용하는 경우, 기본적인 연결 시간 초과는 60초입니다. 이를 늘려보셔야 할 수도 있습니다. 4. NGINX의 버퍼 크기 제한: `proxy_buffers`와 `proxy_buffer_size` 옵션을 확인해 보세요. 동시에 많은 양의 데이터를 처리할 수 없으면 요청이 실패합니다. 5. Express 앱 설정: 이미지 업로드와 같은 대용량 데이터 요청을 다루거나, 비동기 방식으로 동작하는 작업을 처리하기 위해 필요한 특정 설정이 누락되었는지 확인해 보세요. 위 사항들 중 하나라도 해당될 경우, 해결 방법을 찾아서 적용해 보세요. 모든 것을 확인했음에도 문제가 계속된다면, 네트워크 패킷 분석 도구나 로깅 등 다른 디버깅 방법을 사용하여 더 구체적인 원인을 파악해 보실 필요가 있습니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!