[ NGINX ] NGINX를 리버스 프록시로 사용하는 WebSocket 시스템 구축

2025. 7. 30. 20:35·CS 및 기본 개념

WebSocket + Nginx의 이점

우선 처음에 볼 때는 왜 굳이 Nginx를 거쳐가는 것을 통해서 지연을 발생시키는지 이해가 되지 않았다.

 

하지만 아래와 같은 이유로 Nginx를 사용했을 때 얻을 수 있는 이점들이 상당하다.

  • TLS 처리가 가능하다 ( wss, https )
  • Nginx 기반의 로드밸런싱이 가능하다 ( websocket, api 서버 )
  • React 빌드 파일을 정적 파일로 제공

이러한 이유로 클라이언트와 서버의 웹소켓 통신 시 Nginx를 리버시 프록시 서버로 사용해보기로 했다.

 


Why Nginx?

그런데 Nginx 대신 사용할 수 있는 서비스들도 분명히 있다

대표적으로 Apache가 그렇다.

 

따라서 nginx와 Apache를 비교해보면서 어떤 기술이 더 적절할지에 대해서 알아보았다.


Apache 동작 원리와 문제점

Apache는 기본적으로 prcess-per-request 혹은 thread-per-request 방식으로 작동한다.

따라서 사용자의 요청마다 쓰레드나 프로세스를 새로 생성하여 처리하는 방식을 사용한다.

 

이러한 동작 방식으로 인해서 사용자가 많을수록 부담이 심해지는 구조를 갖고있다.

또한 C10K 문제에 취약하다

 

따라서 실시간으로 잦은 데이터 송/수신이 있는 웹소켓에서는 사용을 지양하는 것이 좋을 것이다.


Nginx 동작 원리

반면 Nginx는 event driven 구조의 웹서버 소프트웨어이다.

고정된 수의 프로세스만 생성하여 관리하고, event handler를 통해서 여러개의 요청을 비동기적으로 처리한다.

 

이러한 동작 방식 덕분에 컨텍스트 스위칭과 CPU 비용이 낮고, 적은 양의 스레드로 상대적으로 많은 데이터 처리가 가능하다.

다만, Nginx는 동적 컨텐츠 처리가 불가능하다. 또한 모듈이 Apache에 비해서 상대적으로 적다

 

해당 단점에도 불구하고 현재 구상중인 서비스에서는 Nginx가 보다 적절한 선택이 될 수 있을 것이다.

잦은 데이터 송수신을 상대적으로 적은 자원으로 처리할 수 있기 때문이다.

 


WebSocket

다음으로 Nginx에서 WebSocket 설정을 알아보기 전에 WebSocket 자체에 대해서 간단하게 알아본다


WebSocket 기본 개념

기본적으로 HTTP는 비연결성이고 상대적으로 큰 크기의 헤더를 갖는다.

HTTP에서 양방향 통신 프로토콜을 제공하고 헤더로 인한 오버헤드를 줄이기 위해 탄생한 기술이 WebSocket이다.

 

WebSocket은 TCP 기반으로 전이중 통신 채널을 제공하는 프로토콜이다.

HTTP와 명확히 다른 프로토콜이지만 HTTP 위에서 동작 가능하도록 설계되었기에 기본 포트로 80, 443를 사용하고 HTTP와 높은 호환성을 갖는다

 

WebSocket은 핸드쉐이크 과정에서는 HTTP로 통신을 하기에 헤더 오버헤드가 존재하지만, 그 이후로는 프로토콜을 ws으로 전환하기에 헤더 오버헤드를 줄이고 양방향 통신을 하기에 용이하다.


WebSocket 핸드쉐이크

HTTP 환경에서 웹소켓 프토로콜로 통신하기 위해서는 웹소켓 핸드쉐이크가 필요하다.

기본적으로 핸드쉐이크는 HTTP 기반으로 이루어지고 그 이후부터는 ws 프로토콜로 전환하여 커넥션을 유지하며 통신한다.

 

이 때 프로토콜을 전환하기 위해서는 핸드쉐이크 요청의 헤더에는 다음과 같은 헤더값이 있어야 한다.

Upgrade: "websocket"
Connection: "upgrade"

 

이는 현재 요청을 통해서 ws 프로토콜로 변경하겠다는 것을 의미한다.

 


Websocket에서 리버스 프록시로 Nginx 사용하기

마지막으로 Nginx를 리버시 프록시로 사용하는 방법에 대한 기본 지식들과 예시들을 알아본다.


Nginx 기반의 Websocket의 동작 원리

만약 Nginx를 리버시 프록시로 사용한다면 어떻게 WebSocket이 동작하게 될까?

 

우선 아래와 같은 시나리오로 동작하게 된다.

  1. 클라이언트가 Nginx로 핸드쉐이크 요청을 전달
  2. Nginx는 적절한 헤더를 설정하여 해당 요청을 웹소켓 서버로 전달
  3. Nginx가 중계하는 클라이언트와 서버 간 웹소켓 connection이 생성됨

여기서 클라이언트-Nginx, Nginx-서버 간 2개의 웹소켓 connection이 생성되는 것이 아니다.

클라이언트와 서버 간에는 하나의 tcp 기반의 웹소켓 connection이 생성되고, Nginx는 중간에서 해당 tcp 연결을 적절한 대상에게 전달하는 역할만 하는 것이다.


기본적인 Nginx 기반의 WebSocket 설정

해당 내용은 아래 공식 문서를 참고했다.

https://nginx.org/en/docs/http/websocket.html

 

WebSocket proxying

WebSocket proxying To turn a connection between a client and server from HTTP/1.1 into WebSocket, the protocol switch mechanism available in HTTP/1.1 is used. There is one subtlety however: since the “Upgrade” is a hop-by-hop header, it is not passed f

nginx.org

 

우선 공식 문서에서는 다음과 같은 기본 설정을 제시한다.

upstream backend {
    server backend:8080;
    keepalive 1024;
}

location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 300s;
}

 

여기서 각 설정은 다음과 같은 의미를 갖는다.

  • location /chat/ : /chat/으로 요청을 보내면 /chat을 뺀 남은 경로를 proxy_pass로 전달한다.
  • proxy_pass : location으로 받은 요청을 전달할 대상
  • proxy_http_version : http 버전 설정
    • http 1.1부터 장기적 연결을 지원하기 때문에 웹소켓은 해당 버전 이상을 사용해야 한다.
  • proxy_set_header Upgrade $http_upgrade : websocket 핸드쉐이크 필수 헤더 설정
  • proxy_set_header Connection "upgrade" : websocket 헨드쉐이크 필수 헤더 설정
  • proxy_read_timeout : 웹소켓 연결 타임아웃 설정 ( 기본 : 60초 )

이를 통해서 최적화를 제외한 간단한 웹소켓 연결 설정이 가능하다.


Nginx 기반의 Websocket 최적화 설정

다음으로는 실시간성이 중요한 서비스에서의 웹소켓 설정에 대해서 알아본다.

upstream backend {
    server backend:8080;
    keepalive 1024;
}

location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 300s;
    
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    
    proxy_buffering off;
    gzip off;
    tcp_nodelay on;
}

 

기본적으로 두 가지 분류의 설정이 추가되었다.

  1. 보안 관련 설정
    • proxy_set_header HOST : CORS 등의 보안 관련 설정에서 사용되는 host 정보
    • proxy_set_header X-Real-IP : CORS 등의 보안 관련 설정에서 사용되는 원본 IP 정보
  2. 저지연 관련 설정
    • proxy_buffering off : 데이터를 버퍼에 임시 보관하는 설정을 제거하여 저지연 지원
    • gzip off : 데이터 압축으로 인한 데이터 손상과 지연을 방지한다.
    • tcp_nodelay on : 네트워크에서 작은 데이터를 바로 전송하는 것을 보장하여 저지연 지원

마무리

이번에는 Nginx 기반의 WebSocket 설정에 대해서 알아보았고, 그와 관련된 여러 개념들에 대해서 추가로 공부했다.

 

해당 작업은 단순 서버를 개발하는 것이 아닌 HTTP와 Nginx에 대한 광범위한 개념이 필요한 작업이었다

 

다음에는 HTTP의 각 버전들의 차이에 대해서 공부해볼 예정이다

'CS 및 기본 개념' 카테고리의 다른 글

[ Java 공식문서 ] Java 동시성 프로그래밍 1 : Thread  (3) 2025.08.04
[cs] HTTP 버전별 특징과 차이점  (4) 2025.07.31
[ AWS ] CDN (CloudFront) 으로 S3 정적 파일 관리하기  (3) 2025.07.23
[ CS ] 네트워크 주요 포트번호와 그 사용처  (3) 2025.07.22
[ Java ] Executor 인터페이스로 동시성 관리하기  (1) 2025.07.09
'CS 및 기본 개념' 카테고리의 다른 글
  • [ Java 공식문서 ] Java 동시성 프로그래밍 1 : Thread
  • [cs] HTTP 버전별 특징과 차이점
  • [ AWS ] CDN (CloudFront) 으로 S3 정적 파일 관리하기
  • [ CS ] 네트워크 주요 포트번호와 그 사용처
코드래곤
코드래곤
코드래곤 님의 블로그 입니다.
  • 코드래곤
    코드래곤 님의 블로그
    코드래곤
  • 전체
    오늘
    어제
    • 분류 전체보기 (61)
      • 알고리즘 (3)
        • 그리디 (1)
        • 그래프 (2)
      • 시스템 설계 (6)
      • CS 및 기본 개념 (17)
      • Docker (5)
      • Spring (23)
        • 백준 서비스 구현하기 (1)
        • 기초 개념 (14)
        • MSA (2)
        • JPA (1)
      • Dart (3)
      • Flutter (1)
      • Kubernetes (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
코드래곤
[ NGINX ] NGINX를 리버스 프록시로 사용하는 WebSocket 시스템 구축
상단으로

티스토리툴바