블로그 | NGINX

Node.js 및 Socket.IO(WebSocket API)와 함께 NGINX 및 NGINX Plus 사용

NGINX-F5-수평-검정-유형-RGB의 일부
패트릭 노멘센 썸네일
패트릭 노멘센
2014년 11월 19일 게시

이 게시물에서는 NGINX와 NGINX Plus를 Node.js와 Socket.IO와 함께 사용하는 방법에 대해 설명합니다. WebSocket과 NGINX를 사용하여 실시간 웹 애플리케이션을 구축하는 것에 관한 게시물이 큰 인기를 얻었으므로 이 게시물에서는 Socket.IO를 사용하여 문서와 모범 사례를 계속 소개하겠습니다.

Node.js와 Socket.IO와 함께 NGINX를 사용해야 하는 이유는 무엇입니까?

Socket.IO는 Node.js 애플리케이션의 등장으로 인해 꽤 인기를 얻은 WebSocket API입니다. API는 온라인 게임이나 채팅과 같은 실시간 앱을 쉽게 만들 수 있기 때문에 잘 알려져 있습니다. NGINX 1.3.13 이상 및 모든 NGINX Plus 릴리스는 WebSocket 연결의 프록싱을 지원하므로 Socket.IO를 활용할 수 있습니다. WebSocket 프로토콜은 단일 TCP 연결을 통해 풀이중 또는 양방향 통신을 허용합니다.

프로덕션 환경에서 실행되는 애플리케이션은 일반적으로 포트 80(HTTP), 포트 443(HTTPS) 또는 둘 다에서 실행되어야 합니다. 여러 애플리케이션 구성 요소가 사용자와 상호 작용하거나 포트 80에서 웹 서버를 사용하여 다른 자산을 제공하는 경우 이 작업이 어려울 수 있습니다. 이렇게 하려면 Socket.IO 서버로 프록시 하는 것이 필요하며, NGINX는 이를 위한 가장 좋은 방법입니다. 백엔드 애플리케이션 인스턴스가 하나든 수백 개든, NGINX는 여러 노드를 사용할 때 업스트림의 부하를 분산할 수도 있습니다.

Socket.IO 구성

Node.js를 설치하려면 적절한 배포판을 다운로드하세요 (또는 패키지 관리자를 사용하여 설치하세요). npm install socket.io 명령을 실행하여 Socket.IO를 설치합니다.

이 예에서는 실시간 앱의 Socket.IO 서버가 포트 5000에서 실행 중이라고 가정합니다. 다음은 server.js 노드 애플리케이션 파일에 대한 템플릿입니다. 이는 서버 역할을 하고 들어오는 요청을 Socket.IO 서버를 실행하는 적절한 포트로 라우팅하는 기본 프로그램입니다.

var io = require('socket.io').listen(5000); 
io.sockets.on('connection', function (socket) {
socket.on('닉네임 설정', function (name) {
socket.set('nickname', name, function () {
socket.emit('ready');
});
});

socket.on('msg', function () {
socket.get('nickname', function (err, name) {
console.log('채팅 메시지 ', name);
});
});
});

클라이언트에 전달되는 파일(예: index.html) 에 다음과 같은 JavaScript 코드를 추가합니다. 이 예제에서는 사용자의 브라우저와 웹 소켓을 생성하기 위해 애플리케이션에 대한 연결을 요청합니다.

<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io(); // 여기에 초기화 코드를 넣으세요.
</script>

NGINX 구성

상류 선언

애플리케이션에 여러 인스턴스가 있는 경우 NGINX와 NGINX Plus는 부하를 분산하고 사용자 세션을 여러 노드에 분산할 수 있습니다. NGINX 또는 NGINX Plus 구성의 http 컨텍스트에서 업스트림 그룹의 노드를 정의하기 위해 업스트림 블록을 포함합니다.

다음 예에서 보듯이 서버 지시문에 가중치 매개변수를 포함시켜 해당 지시문으로 전송되는 트래픽 비율을 설정할 수 있습니다. 여기서 srv1.app.com은 다른 서버보다 5배 더 많은 세션을 수신합니다. NGINX Plus는 향상된 부하 분산 방법을 통해 NGINX의 역방향 프록시 기능을 확장하고 세션 지속성, 상태 검사, 확장된 상태 보고서, 부하 분산 서버 그룹의 즉석 재구성 기능을 추가합니다.

# http{} 구성 블록에서
upstream socket_nodes {
ip_hash;
server srv1.app.com:5000 weight=5;
server srv2.app.com:5000;
server srv3.app.com:5000;
server srv4.app.com:5000;
}

가상 호스트 구성

이제 업스트림 서버 그룹이 선언되었으므로 가상 서버를 구성하여 해당 그룹으로 트래픽을 전송해야 합니다. 최소한 proxy_pass 지시어를 포함하고 업스트림 그룹의 이름을 지정하세요. WebSocket 프로토콜은 HTTP/1.1에 도입된 Upgrade 헤더를 사용하므로 proxy_http_version 지시문을 포함합니다.

서버 {
server_name app.domain.com;
location / {
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header 호스트 $host;
proxy_pass http://socket_nodes;
}
}

정적 파일은 어떤가요?

정적 자산을 제공하려면 NGINX 프록시 요청을 업스트림 Node.js 인스턴스로 보낼 수 있지만 대부분의 경우 NGINX에서 직접 제공하는 것이 더 효율적입니다.

위의 server 블록의 server_name 지시문과 함께 다음 location 블록은 NGINX에게 로컬 /path/to/assets 디렉터리에서 http://app.domain.com/assets/ 의 콘텐츠를 제공하여 클라이언트가 해당 콘텐츠를 요청하면 응답하도록 지시합니다. 사용자의 요구 사항에 맞게 정적 파일 처리를 더욱 최적화하거나 캐시 만료 설정을 지정할 수 있습니다.

위치 /자산 {
별칭 /path/to/assets;
액세스 로그 꺼짐;
만료 최대;
}

문제 해결

다음 오류가 발생하는 경우 NGINX 1.3 이전 버전을 사용하고 있을 가능성이 높습니다. NGINX 1.3.13 이상에서는 WebSocket 사용이 지원됩니다.

'...'에 대한 WebSocket 연결이 실패했습니다: WebSocket 핸드셰이크 중 오류 발생: 'Connection' 헤더 값이 'Upgrade'가 아닙니다: keep-alive socket.io.js:2371

추가 읽기

NGINX Plus를 사용해보려면 오늘 무료 30일 체험판을 시작하거나 저희에게 연락해 사용 사례에 대해 논의해 보세요.


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