본문 바로가기
Q&A해결2026년 7월 13일2분 읽기

nginx 뒤에 socket.io 붙였더니 websocket이 자꾸 502 뜨는데 폴링으로만 연결돼요

n
nginx_hyewon
조회 1163댓글 4

사내 대시보드에 실시간 알림 붙이려고 socket.io 서버(노드)를 nginx 리버스프록시 뒤에 뒀는데요. 브라우저 개발자도구 네트워크 보면 처음 몇 초는 polling으로 붙었다가 websocket으로 업그레이드하는 순간 502가 뜹니다. 폴링으로는 그럭저럭 동작은 하는데 계속 롱폴링이라 찝찝해서요.

nginx conf는 대충 이렇게 잡았습니다.

location /socket.io/ {
    proxy_pass http://127.0.0.1:3001;
    proxy_set_header Host $host;
}

노드쪽 로그엔 에러가 안 남고 nginx error.log에만 이런 줄이 찍혀요.

*128 upstream prematurely closed connection while reading response header from upstream, ... "GET /socket.io/?EIO=4&transport=websocket HTTP/1.1"

구글링해서 proxy_read_timeout도 올려봤는데 그대로네요. 뭘 빠뜨린 걸까요?

댓글 4

김김영삼3개월 전
업그레이드 헤더가 빠져서 그래요. websocket은 HTTP 커넥션을 Upgrade 하는 건데 지금 conf는 그 핸드셰이크를 프록시가 그대로 전달을 안 하고 있어요. 그래서 노드가 웹소켓 핸드셰이크를 못 받고 커넥션이 끊기는 거고, nginx 입장에선 upstream이 응답헤더 주기 전에 닫아버린 걸로 보여서 502가 뜨는 거예요.

location 안에 이 세 줄 넣어보세요.

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

기본 프록시가 HTTP/1.0으로 붙어서 Upgrade가 안 먹는 경우가 대부분이라 proxy_http_version 1.1이 핵심이에요. 그리고 Connection 헤더를 upgrade로 넘겨줘야 노드가 핸드셰이크를 완성합니다. 이거 넣으면 폴링에서 websocket으로 넘어갈 때 502 안 뜰 거예요.
nnginx_hyewon(guest)3개월 전
오 바로 되네요! 근데 다른 location에선 Connection을 close나 keep-alive로 쓰던데, upgrade로 고정해두면 일반 요청엔 문제 없나요? map 쓰라는 글도 봐서요.
김김영삼3개월 전
좋은 지적이에요. Connection "upgrade"로 하드코딩하면 웹소켓 아닌 일반 요청도 매번 Connection: upgrade가 붙는데, 대부분 백엔드는 무시해서 큰 탈은 없지만 깔끔하진 않죠. 정석은 map으로 조건부로 넘기는 거예요.

http 블록(server 바깥)에 이렇게 두고,

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

location 안에선 proxy_set_header Connection $connection_upgrade; 로 쓰면 업그레이드 요청일 때만 upgrade, 아니면 close로 나갑니다. socket.io 한 곳만 쓰면 하드코딩도 실무상 괜찮지만 프록시 여러 개면 map이 관리하기 훨씬 편해요.
nnginx_hyewon(guest)3개월 전
map까지 적용했습니다. 폴링 안 거치고 처음부터 바로 websocket으로 붙네요. 감사합니다 🙏
Ctrl+Enter로 등록