첫 번째 HTTP 요청이 WebSocket 동작 때문에 지연되는 이유와 프로덕션 환경에서 어떻게 처리되는가?
발행: (2025년 12월 27일 오후 11:32 GMT+9)
7 min read
원문: Dev.to
Source: Dev.to
해당 텍스트가 제공되지 않았습니다. 번역할 내용이 있으면 알려주시면 바로 번역해 드리겠습니다.
Problem Description
저는 FastAPI 백엔드와 개발 중에 Live Server가 제공하는 프런트엔드로 웹 애플리케이션을 구축하고 있습니다. 엔드포인트에 대한 첫 번째 HTTP 요청이 이후 요청들에 비해 눈에 띄게 느립니다.
관찰
- 두 번째 요청 – 빠르게 완료됩니다.
- 첫 번째 요청 – 지연이 발생합니다.
- 동일한 엔드포인트를 OpenAPI Docs(FastAPI가 자동 생성)에서 호출하면, 첫 번째 호출이라도 응답이 즉시 반환됩니다.
- 브라우저 DevTools에서 Live Server가 자동으로 열어주는 웹소켓 연결을 확인했습니다. 이 웹소켓이 일반 HTTP 요청과 자원을 경쟁하여 초기 지연을 일으키는 것으로 보입니다.
질문
- 엔지니어들은 실시간 알림용 WebSocket 연결과 일반 HTTP 요청이 모두 필요한 프로덕션 상황을 어떻게 처리하나요?
- 동일한 프론트엔드 코드가 두 종류의 연결을 시작하더라도 서로 간섭하지 않도록 하는 기술은 무엇인가요?
- WebSocket과 HTTP 트래픽이 같은 클라이언트 코드에서 발생할 경우, 기업들은 라이브 환경에서 충돌을 어떻게 방지하나요?
- API 게이트웨이나 별도의 서브도메인이 사용될 수 있다고 생각하지만, 일반적인 프로덕션 설정에 대한 간단한 설명을 듣고 싶습니다.
Production‑Ready Approaches
1. Separate Hostnames / Subdomains
- WebSocket endpoint 은 별도의 호스트명(예:
ws.example.com)에 노출되고 REST/GraphQL API 는api.example.com에 존재합니다. - 브라우저는 이를 독립된 오리진으로 취급하므로 연결 제한, TLS 세션, 소켓 풀 등이 서로 간섭하지 않습니다.
- DNS와 TLS 인증서는 와일드카드 또는 SAN 인증서를 사용해 함께 관리할 수 있어 설정이 간단합니다.
2. Dedicated Load Balancers / Reverse Proxies
- Layer‑7 로드 밸런서(예: NGINX, HAProxy, Envoy, AWS ALB)는
Upgrade: websocket요청을 WebSocket 전용 백엔드 풀로 라우팅하고 일반 HTTP 요청은 별도 풀로 전달합니다. - 로드 밸런서는 각 프로토콜에 대해 별도의 연결 풀을 유지해 자원 경쟁을 방지합니다.
3. Connection‑Pooling Isolation in the Client
- 최신 브라우저는 이미 오리진 및 프로토콜별로 별도의 연결 풀을 유지합니다.
- 프론트엔드 라이브러리(
fetch,axios,WebSocket)는 서로 다른 기본 소켓을 사용하므로 오리진이 다르면 서로 차단되지 않습니다. - 동일 오리진에서 두 종류의 연결을 제공해야 한다면, 서버가 동시 업그레이드를 처리할 수 있는지 확인하세요(대부분의 프로덕션 급 서버는 지원합니다).
4. Use of API Gateways / Service Meshes
- API 게이트웨이(Kong, Apigee, AWS API Gateway)는 단일 도메인 아래에서 HTTP와 WebSocket 라우트를 모두 노출하면서 내부적으로는 서로 다른 서비스로 라우팅할 수 있습니다.
- 게이트웨이가 프로토콜 처리를 추상화하므로 클라이언트는 하나의 엔드포인트만 보지만 트래픽은 격리됩니다.
5. Scaling and Resource Allocation
- WebSocket 서비스는 별도의 인스턴스(또는 컨테이너)에서 실행하고, 무상태 HTTP API와는 분리합니다.
- 이렇게 하면 WebSocket 연결 급증이 HTTP 요청 처리에 필요한 CPU, 메모리, 파일 디스크립터 한도를 소모하는 것을 방지할 수 있습니다.
6. CORS and Security Headers
- 적절한 CORS 설정을 통해 브라우저가 동일 프론트엔드 오리진에서 두 종류의 연결을 허용하도록 하여 불필요한 프리플라이트 지연을 최소화합니다.
- 보안 헤더(예:
Upgrade-Insecure-Requests)를 조정해 추가 라운드‑트립을 피할 수 있습니다.
왜 프로덕션에서 작동하는가
- 별도의 출처 또는 라우팅 규칙은 브라우저의 연결 제한(일반적으로 호스트당 6개의 동시 연결)이 WebSocket과 HTTP 트래픽 사이에서 공유되지 않도록 보장합니다.
- 프로덕션 서버는
Upgrade헤더를 효율적으로 처리하도록 구성되어 있어, 일반 HTTP 요청을 처리하는 스레드를 차단하지 않고 WebSocket을 설정합니다. - 로드 밸런서와 게이트웨이는 HTTP와 WebSocket 서비스의 이벤트 루프를 독립적으로 유지하므로, 장시간 지속되는 WebSocket이 요청 워커를 고갈시키지 않습니다.
TL;DR
- 실제 운영 환경에서는 WebSocket과 HTTP 트래픽을 보통 호스트명, 리버스‑프록시 라우팅, 혹은 API 게이트웨이를 통해 분리합니다.
- 이러한 분리는 두 프로토콜이 동일한 연결 풀이나 서버 자원을 놓고 경쟁하지 않도록 방지합니다.
- 프런트엔드는 동일한 코드베이스에서 두 연결을 모두 시작할 수 있으며, 기반 인프라가 서로 간섭 없이 나란히 동작하도록 보장합니다.