블로그 | NGINX

WebSocket 프록시로서의 NGINX

NGINX-F5-수평-검정-유형-RGB의 일부
릭 넬슨 썸네일
릭 넬슨
2014년 5월 16일 게시

WebSocket 프로토콜은 클라이언트와 서버 간의 실시간 양방향 통신을 지원하는 웹 애플리케이션을 만드는 방법을 제공합니다. HTML5의 일부인 WebSocket을 사용하면 이전에 사용 가능했던 방법보다 이러한 유형의 애플리케이션을 훨씬 더 쉽게 개발할 수 있습니다. Chrome, Firefox, Internet Explorer, Opera, Safari를 포함하여 대부분의 최신 브라우저는 WebSocket을 지원하고 있으며, 점점 더 많은 서버 애플리케이션 프레임워크도 WebSocket을 지원하고 있습니다.

성능과 고가용성을 위해 여러 대의 WebSocket 서버가 필요한 엔터프라이즈 프로덕션 사용의 경우 WebSocket 프로토콜을 이해하는 부하 분산 계층이 필요하며, NGINX는 버전 1.3부터 WebSocket을 지원하여 역방향 프록시 역할을 수행하고 WebSocket 애플리케이션의 부하 분산을 수행할 수 있습니다. (NGINX Plus의 모든 릴리스는 WebSocket도 지원합니다.)

WebSocket 연결의 부하를 분산하기 위한 NGINX의 확장성에 대한 최근 성능 테스트를 확인해 보세요.

WebSocket 프로토콜은 HTTP 프로토콜과 다르지만, WebSocket 핸드셰이크는 HTTP와 호환되며 HTTP 업그레이드 기능을 사용하여 HTTP에서 WebSocket으로 연결을 업그레이드합니다. 이를 통해 WebSocket 애플리케이션을 기존 인프라에 더 쉽게 적용할 수 있습니다. 예를 들어, WebSocket 애플리케이션은 표준 HTTP 포트 80 및 443을 사용하여 기존 방화벽 규칙을 사용할 수 있습니다.

WebSocket 애플리케이션은 클라이언트와 서버 간의 장기 연결을 열어두어 실시간 애플리케이션 개발을 용이하게 해줍니다. HTTP에서 WebSocket으로 연결을 업그레이드하는 데 사용되는 HTTP 업그레이드 메커니즘은 업그레이드연결 헤더를 사용합니다. WebSocket을 지원하는 데 있어 역방향 프록시 서버는 몇 가지 과제에 직면합니다. 첫 번째는 WebSocket이 홉 바이 홉 프로토콜이기 때문에 프록시 서버가 클라이언트의 업그레이드 요청을 가로채면 적절한 헤더를 포함하여 백엔드 서버로 자체 업그레이드 요청을 보내야 한다는 것입니다. 또한 WebSocket 연결은 HTTP에서 사용하는 일반적인 단기간 연결과 달리 장시간 지속되므로 역방향 프록시는 연결이 유휴 상태인 것처럼 보인다고 해서 연결을 닫는 것이 아니라 연결이 계속 열려 있도록 허용해야 합니다.

NGINX는 클라이언트와 백엔드 서버 사이에 터널을 설정하여 WebSocket을 지원합니다. NGINX가 클라이언트에서 백엔드 서버로 업그레이드 요청을 보내려면 이 예와 같이 업그레이드연결 헤더를 명시적으로 설정해야 합니다.

위치 /wsapp/ { proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_set_header 호스트 $host;
}

이 작업이 완료되면 NGINX는 이를 WebSocket 연결로 처리합니다.

NGINX 웹소켓 예제

다음은 NGINX가 WebSocket 프록시로 작동하는 것을 보여주는 라이브 예입니다. 이 예제에서는 Node.js 기반으로 구축된 WebSocket 구현인 ws 를 사용합니다. NGINX는 ws 와 Node.js를 활용하여 간단한 WebSocket 애플리케이션의 역방향 프록시 역할을 합니다. 이 지침은 Ubuntu 13.10과 CentOS 6.5에서 테스트되었지만 다른 OS 및 버전에 맞게 조정이 필요할 수 있습니다. 이 예에서 WebSocket 서버의 IP 주소는 192.168.100.10이고 NGINX 서버의 IP 주소는 192.168.100.20입니다.

  1. 아직 Node.js와 npm이 설치되어 있지 않다면 다음 명령을 실행하세요.

    • Debian 및 Ubuntu의 경우:

      $ sudo apt-get 설치 nodejs npm
    • RHEL 및 CentOS의 경우:

      $ sudo yum install nodejs npm
  2. Node.js는 Ubuntu에서는 nodejs 로, CentOS에서는 node 로 설치됩니다. 이 예제에서는 node를 사용하므로 Ubuntu에서는 nodejs 에서 node 로의 심볼릭 링크를 만들어야 합니다.

    $ ln -s /usr/bin/nodejs /usr/local/bin/노드
  3. ws 를 설치하려면 다음 명령을 실행하세요.

    $ sudo npm 설치 ws

    메모: 오류 메시지가 나타나는 경우: “오류: 레지스트리에서 가져오지 못했습니다: ws”, 다음 명령을 실행하여 문제를 해결하세요:

    $ sudo npm config set 레지스트리 http://registry.npmjs.org/

    그런 다음 sudo npm install ws 명령을 다시 실행합니다.

  4. ws 에는 클라이언트로 사용할 /root/node_modules/ws/bin/wscat 프로그램이 함께 제공되지만 서버 역할을 할 프로그램을 만들어야 합니다. 다음 내용으로 server.js 라는 파일을 만듭니다.

    console.log("서버 시작됨");
    var Msg = '';
    var WebSocketServer = require('ws').Server
    , wss = new WebSocketServer({port: 8010});
    wss.on('connection', function(ws) {
    ws.on('message', function(message) {
    console.log('클라이언트로부터 수신: %s', message);
    ws.send('서버가 클라이언트로부터 수신: ' + message);
    });
    });
  5. 서버 프로그램을 실행하려면 다음 명령을 실행하세요.
    $ 노드 서버.js
  6. 서버는 "서버 시작" 이라는 초기 메시지를 인쇄한 다음 포트 8010에서 수신 대기하며 클라이언트가 연결될 때까지 기다립니다. 클라이언트의 요청을 받으면 이를 에코하고, 수신한 메시지가 포함된 메시지를 클라이언트로 다시 보냅니다. NGINX가 이러한 요청을 프록시하게 하려면 다음 구성을 만듭니다. 요청의 Upgrade 헤더가 '' 로 설정되면 Connection 헤더도 올바르게 닫히 도록 블록을 추가하고 있습니다.

    http {
    맵 $http_upgrade $connection_upgrade {
    기본 업그레이드;
    '' 닫기;
    }
    
    업스트림 웹소켓 {
    서버 192.168.100.10:8010;
    }
    
    서버 {
    수신 8020;
    위치 / {
    proxy_pass http://websocket;
    proxy_http_version 1.1;
    proxy_set_header 업그레이드 $http_upgrade;
    proxy_set_header 연결 $connection_upgrade;
    proxy_set_header 호스트 $host;
    }
    }
    }

    NGINX는 포트 8020에서 수신하고 백엔드 WebSocket 서버로 요청을 프록시합니다. proxy_set_header 지시어를 사용하면 NGINX가 WebSocket 프로토콜을 올바르게 처리할 수 있습니다.

  7. 서버를 테스트하기 위해 클라이언트로 wscat을 실행합니다.

    $ /root/node_modules/ws/bin/wscat --연결 ws://192.168.100.20:8020

    wscat은 NGINX 프록시를 통해 WebSocket 서버에 연결합니다. wscat에 서버로 보낼 메시지를 입력하면 서버에 메시지가 에코된 후, 서버의 메시지가 클라이언트에 나타납니다. 다음은 상호작용의 예입니다.

    섬기는 사람: 고객:
    $ 노드 서버.js
    서버 시작됨
     
     
     
     
     
    wscat --연결 ws://192.168.100.20:8020
    연결됨 (종료하려면 CTRL+C를 누르세요)
    > 안녕하세요
    클라이언트로부터 수신: 안녕하세요
    < 서버가 클라이언트로부터 수신함: 안녕하세요

    여기서는 클라이언트와 서버가 프록시 역할을 하는 NGINX를 통해 통신하고, 클라이언트나 서버의 연결이 끊어질 때까지 계속해서 메시지를 주고받을 수 있는 것을 볼 수 있습니다. NGINX가 WebSocket을 제대로 처리하는 데 필요한 것은 HTTP에서 WebSocket으로 연결을 업그레이드하는 업그레이드 요청을 처리하도록 헤더를 제대로 설정하는 것입니다.

추가 읽기


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."