WebSocket vs HTTP — 소켓으로 몰면 잃는 것

네트워킹2분조회

실시간 기능을 붙이다 보면 “그냥 다 WebSocket 으로 하면 되지 않나” 는 생각이 듭니다. 그런데 REST 에서 소켓으로 옮기면 얻는 것(양방향·실시간)만큼 잃는 것이 큽니다. 그 손실을 알아야 어디에 소켓을 쓸지 정해집니다.

상태를 갖게 되어 수평 확장이 막힘

HTTP 요청은 무상태라 어느 서버 인스턴스로 가든 상관없고, 그래서 인스턴스를 늘리면 그대로 부하가 분산됩니다.

WebSocket 은 연결이 특정 노드에 묶입니다. 한 번 연결되면 그 소켓은 그 인스턴스가 붙들고 있습니다. 그래서 A 노드에 붙은 사용자와 B 노드에 붙은 사용자가 서로 메시지를 주고받으려면, 노드 사이를 잇는 장치(예: Redis pub/sub)가 따로 필요합니다. 무상태였다면 공짜였을 수평 확장이, 상태를 갖는 순간 별도 설계가 됩니다.

HTTP 인프라를 못 씀

REST 위에는 그동안 쌓인 인프라가 있습니다. 소켓으로 옮기면 이걸 못 씁니다.

  • CDN·캐시 — 응답을 캐시하고 ETag 로 재검증하는 층. 소켓 스트림엔 안 붙습니다.
  • 경로 기반 라우팅 — ALB 의 Host/Path 라우팅. 소켓은 한 번 맺으면 계속 같은 연결이라 경로별 분기가 안 맞습니다.
  • WAF·rate limit — 요청 단위로 거는 보호 장치. 지속 연결엔 그대로 안 걸립니다.

나머지도 직접 구현

  • 관측성 — 요청/응답 로그가 자동으로 안 남으니 직접 계측해야 합니다.
  • 요청-응답 짝짓기 — HTTP 는 요청과 응답이 1:1 이지만, 소켓은 메시지가 양방향으로 흐르니 “이 응답이 어느 요청의 것인지” 를 직접 붙여야 합니다.
  • 재연결 복구 — 끊겼을 때 다시 붙고 상태를 복구하는 로직이 내 몫입니다.
  • 유휴 비용 — 아무것도 안 하는 사용자도 연결 유지(ping)로 자원을 씁니다.

WebSocket 선택 기준

판단 기준은 하나로 좁혀집니다.

  • 서버가 먼저 말해야 하나? → WebSocket. 채팅, 실시간 알림, 협업 편집처럼 서버가 클라이언트에 능동적으로 밀어야 하는 경우.
  • 캐시 가능한 요청-응답인가? → REST. 클라이언트가 물을 때만 답하면 되는 경우.

WebSocket이 가져가는 것 — 무상태·HTTP 인프라·관측성

WebSocket 은 양방향·실시간을 주는 대신, 무상태·HTTP 인프라·자동 관측성을 가져갑니다. 실시간처럼 보인다고 다 소켓이 답은 아닙니다. “서버가 먼저 말해야 하는가” 가 아니라면, REST 로 두고 잃지 않는 편이 낫습니다.

  1. 불러오는 중