The WebSocket 프로토콜은 클라이언트와 서버 간의 실시간 양방향 통신을 지원하는 웹 애플리케이션을 만들 수 있는 방법을 제공합니다. HTML5의 일부인 WebSocket을 사용하면 이전에 사용하던 방식보다 이러한 유형의 애플리케이션을 훨씬 쉽게 개발할 수 있습니다. Chrome, Firefox, Internet Explorer, Opera, Safari를 비롯한 대부분의 최신 브라우저가 WebSocket을 지원하며, WebSocket을 지원하는 서버 애플리케이션 프레임워크도 점점 늘어나고 있습니다.
성능과 고가용성을 위해 여러 WebSocket 서버가 필요한 엔터프라이즈 프로덕션 환경에서는 WebSocket 프로토콜을 이해하는 부하 분산 계층이 필요합니다. NGINX는 버전 1.3부터 WebSocket을 지원해 왔으며, 리버스 프록시 역할을 하고 WebSocket 애플리케이션의 부하 분산을 수행할 수 있습니다. (NGINX Plus의 모든 릴리스도 WebSocket을 지원합니다.)
최근 진행된 성능 테스트에서 NGINX가 WebSocket 연결을 로드 밸런싱할 때의 확장성을 확인해 보세요.
WebSocket 프로토콜은 HTTP 프로토콜과 다르지만, WebSocket 핸드셰이크는 HTTP와 호환되며 HTTP Upgrade 기능을 사용하여 연결을 HTTP에서 WebSocket으로 업그레이드합니다. 따라서 WebSocket 애플리케이션을 기존 인프라에 더 쉽게 통합할 수 있습니다. 예를 들어 WebSocket 애플리케이션은 표준 HTTP 포트인 80과 443을 사용할 수 있으므로 기존 방화벽 규칙을 그대로 적용할 수 있습니다.
WebSocket 애플리케이션은 클라이언트와 서버 간의 연결을 장시간 열린 상태로 유지하므로 실시간 애플리케이션을 쉽게 개발할 수 있습니다. HTTP 연결을 WebSocket으로 업그레이드하는 데 사용되는 HTTP Upgrade 메커니즘은 Upgrade 및 Connection 헤더를 사용합니다. 리버스 프록시 서버가 WebSocket을 지원할 때는 몇 가지 해결해야 할 문제가 있습니다. 그중 하나는 WebSocket이 홉별(hop-by-hop) 프로토콜이라는 점입니다. 따라서 프록시 서버가 클라이언트의 Upgrade 요청을 가로채면 적절한 헤더를 포함한 자체 Upgrade 요청을 백엔드 서버로 보내야 합니다. 또한 WebSocket 연결은 HTTP에서 일반적으로 사용하는 단기 연결과 달리 장시간 유지되므로, 리버스 프록시는 이러한 연결이 유휴 상태로 보인다는 이유로 종료하지 않고 열린 상태로 유지해야 합니다.
NGINX는 클라이언트와 백엔드 서버 간에 터널을 설정할 수 있도록 하여 WebSocket을 지원합니다. NGINX가 클라이언트의 Upgrade 요청을 백엔드 서버로 보내려면 다음 예와 같이 Upgrade 및 Connection 헤더를 명시적으로 설정해야 합니다:
location /wsapp/ { proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}이 작업이 완료되면 NGINX는 이를 WebSocket 연결로 처리합니다.
NGINX WebSocket 예제
다음은 NGINX가 WebSocket 프록시로 작동하는 모습을 보여 주는 실제 예제입니다. 이 예제에서는 ws라는 Node.js 기반 WebSocket 구현을 사용합니다. NGINX는 ws와 Node.js를 사용하는 간단한 WebSocket 애플리케이션의 리버스 프록시 역할을 합니다. 이 지침은 Ubuntu 13.10 및 CentOS 6.5에서 테스트되었지만, 다른 OS 및 버전에서는 조정이 필요할 수 있습니다. 이 예제에서 WebSocket 서버의 IP 주소는 192.168.100.10이고 NGINX 서버의 IP 주소는 192.168.100.20입니다.
- Node.js와 npm이 아직 설치되어 있지 않다면 다음 명령을 실행합니다:
- Debian 및 Ubuntu의 경우:
$ sudo apt-get install nodejs npm- RHEL 및 CentOS의 경우:
$ sudo yum install nodejs npm- Node.js는 Ubuntu에서는
nodejs로, CentOS에서는node로 설치됩니다. 이 예제에서는node를 사용하므로 Ubuntu에서는nodejs에서node로 연결되는 심볼릭 링크를 만들어야 합니다:
$ ln -s /usr/bin/nodejs /usr/local/bin/node- 설치하려면 ws 다음 명령어를 실행하세요:
$ sudo npm install ws- 참고: “Error: failed to fetch from registry: ws”라는 오류 메시지가 표시되면 다음 명령어를 실행하여 문제를 해결하세요:
$ sudo npm config set registry http://registry.npmjs.org/- 그런 다음
sudo npm install ws명령을 다시 실행합니다. - ws에는 클라이언트로 사용할 프로그램인 /root/node_modules/ws/bin/wscat이 포함되어 있지만, 서버 역할을 할 프로그램은 직접 만들어야 합니다. 다음 내용으로 server.js 파일을 만드세요:
console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8010});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('Received from client: %s', message);
ws.send('Server received from client: ' + message);
});
});- 서버 프로그램을 실행하려면 다음 명령어를 실행하세요:
$ node server.js- 서버는 먼저
"Serverstarted"메시지를 출력한 다음 포트 8010에서 수신 대기하며 클라이언트가 연결되기를 기다립니다. 클라이언트 요청을 받으면 해당 요청을 그대로 출력하고, 수신한 메시지가 포함된 응답 메시지를 클라이언트에 보냅니다. NGINX가 이러한 요청을 프록시하도록 다음 구성을 만듭니다. 요청의map블록을 추가하여 요청의Upgrade헤더가''로 설정된 경우Connection헤더가close로 올바르게 설정되도록 합니다.
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 192.168.100.10:8010;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
}- NGINX는 8020 포트에서 수신 대기하며 요청을 백엔드 WebSocket 서버로 프록시합니다.
proxy_set_header지시어를 사용하면 NGINX가 WebSocket 프로토콜을 올바르게 처리할 수 있습니다. - 서버를 테스트하기 위해 wscat을 클라이언트로 실행합니다:
$ /root/node_modules/ws/bin/wscat --connect ws://192.168.100.20:8020- wscat은 NGINX 프록시를 통해 WebSocket 서버에 연결됩니다. wscat이 서버로 보낼 메시지를 입력하면 해당 메시지가 서버에 표시된 후 서버에서 보낸 메시지가 클라이언트에 나타납니다. 다음은 상호 작용의 예입니다. 서버: 클라이언트:
$node server.js서버 시작됨
wscat --connect ws://192.168.100.20:8020
연결됨(종료하려면 CTRL+C를 누르세요)
> Hello클라이언트로부터 수신: Hello< 서버가 클라이언트로부터 수신함: Hello여기에서 클라이언트와 서버가 프록시 역할을 하는 NGINX를 통해 통신할 수 있으며, 클라이언트나 서버 중 하나가 연결을 끊을 때까지 메시지를 계속 주고받을 수 있음을 확인할 수 있습니다. NGINX가 WebSocket을 올바르게 처리하도록 하려면 HTTP 연결을 WebSocket으로 전환하는 Upgrade 요청을 처리할 수 있도록 헤더를 올바르게 설정하기만 하면 됩니다.
추가 자료
- WebSocket 프록시(nginx.org)
- NGINX와 NGINX Plus 기능 비교
- NGINX Plus 기술 사양
- WebSocket 트래픽 프록시 구성 참조:
작성자 소개

관련 블로그 게시물
시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.
F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.
진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.
NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.
Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.