WebSocket API와 함께 NGINX 사용하기
이 포스트에서는 Node.js 및 Socket.IO와 함께 NGINX 및 NGINX Plus를 사용하는 방법에 대해 설명합니다. WebSocket 및 NGINX를 사용하여 실시간 웹 애플리케이션을 구축하는 방법에 대한 포스트가 꽤 유명하므로 이 포스트에서는 Socket.IO를 사용하여 문서 및 모범 사례를 계속 설명하겠습니다.
목차
1. Node.js 및 Socket.IO와 함께 NGINX를 사용하는 이유
2. Socket.IO 구성
3. WebSocket NGINX 구성
3-1. Upstream 선언
3-2. 가상 호스트 구성
3-3. 정적 파일은 어떻습니까?
4. WebSocket 문제 해결
5. WebSocket 참고 자료
1. 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는 여러 노드를 사용할 때 upstream의 부하를 분산할 수도 있습니다.
2. 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('set nickname', function (name) {
socket.set('nickname', name, function () {
socket.emit('ready');
});
});
socket.on('msg', function () {
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
});
});
});
클라이언트에 전달되는 파일(예: index.html)에 다음과 같은 JavaScript 코드를 추가합니다. 이 예제에는 사용자의 브라우저로 WebSocket을 생성하기 위해 애플리케이션에 대한 연결을 요청합니다.
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io(); // your initialization code here.
</script>
3. WebSocket NGINX 구성
3-1. Upstream 선언
애플리케이션에 여러 인스턴스가 있는경우 NGINX 및 NGINX Plus는 로드 밸런싱을 수행하고 사용자 세션을 여러 노드에 분산할 수 있습니다. NGINX 또는 NGINX Plus 구성의 http 컨텍스트에서 upstream 그룹의 노드를 정의하는 Upstream 블록을 포함합니다.
다음 예에서와 같이 server 지시문에 가중치 매개변수를 포함하여 전달되는 트래픽의 비율을 설정할 수 있습니다. 여기서 srv1.app.com은 다른 서버보다 5배 더 많은 세션을 수신합니다. NGINX Plus는 향상된 로드 밸런싱 방법과 세션 지속성, 상태 검사, 확장된 보고서 및 로드 밸런싱된 서버 그룹의 즉각적인 재구성을 추가하여 NGINX의 reverse proxy 기능을 확장합니다.
# in the http{} configuration block
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;
}
3-2. 가상 호스트 구성
이제 서버의 upstream 그룹이 선언되었으므로 트래픽을 전달하도록 가상 서버를 구성해야 합니다. 최소한 proxy_pass 지시문을 포함하고 upstream 그룹이 이름을 지정하십시오. WebSocket 프로토콜은 HTTP/1.1에 도입된 Upgrade 헤더를 사용하기 때문에 proxy_http_version 지시문을 포함합니다.
server {
server_name app.domain.com;
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://socket_nodes;
}
}
3-3. 정적 파일은 어떻습니까?
정적 자산을 제공하기 위해 upstream Node.js 인스턴스에 대한 NGINX 프록시 요청을 가질 수 있지만 대부분의 경우 NGINX가 직접 제공하도록 하는 것이 더 효율적입니다.
위의 server 블록의 server_name 지시문과 함께 다음 location 블록은 NGINX에게 http://app.domain.com/assets/ 경로의 콘텐츠 요청에 대해 로컬 /path/to/assets 디렉토리에서 서비스하도록 지시합니다. 정적 파일 처리를 더 최적화하거나 필요에 맞게 캐시 만료 설정을 조정할 수 있습니다.
location /assets {
alias /path/to/assets;
access_log off;
expires max;
}
4. WebSocket 문제 해결
다음 오류가 발생하면 1.3 이전 버전의 NGINX를 실행 중일 수 있습니다. WebSocket 사용은 NGINX 1.3.13 이상에서 지원됩니다.
WebSocket connection to '...' failed: Error during WebSocket handshake: 'Connection' header value is not 'Upgrade': keep-alive socket.io.js:2371
5. WebSocket 참고 자료
NGINX Plus를 사용해 보려면 지금 무료 30일 평가판을 시작하거나 NGINX STORE에 연락하여 사용 사례에 대해 논의하십시오.
사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.