nginx為WebSocket做反向代理,WebSocket伺服器連線302
對於企業生產用途,需要多個WebSocket伺服器來實現效能和高可用性,需要了解WebSocket協議的負載平衡層,NGINX自1.3版本起支援WebSocket,並可作為反向代理,並進行WebSocket的負載平衡應用。(所有版本的NGINX Plus也支援WebSocket。)
檢視關於NGINX可擴充套件性的最新效能測試,以負載平衡WebSocket連線。
WebSocket協議與HTTP協議不同,但WebSocket握手與HTTP相容,使用HTTP升級工具將連線從HTTP升級到WebSocket。這允許WebSocket應用程式更容易地適應現有的基礎架構。例如,WebSocket應用程式可以使用標準HTTP埠80和443,從而允許使用現有的防火牆規則。
WebSocket應用程式可以在客戶端和伺服器之間保持長時間執行的連線,從而有助於開發實時應用程式。用於將連線從HTTP升級到WebSocket的HTTP升級機制使用Upgrade和Connection頭。反向代理伺服器在支援WebSocket時面臨一些挑戰。一個是WebSocket是一個逐跳協議,因此當代理伺服器攔截客戶端的升級請求時,需要向後端伺服器傳送自己的升級請求,包括相應的標頭檔案。此外,由於WebSocket連線長期存在,與HTTP使用的典型短期連線相反,反向代理需要允許這些連線保持開啟狀態,而不是關閉它們,因為它們似乎處於空閒狀態。
允許在客戶機和後端伺服器之間建立隧道,NGINX支援WebSocket。對於NGINX將升級請求從客戶端傳送到後臺伺服器,必須明確設定Upgrade和Connection標題,如下例所示:
location /wsapp/ { proxy_pass http://wsbackend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; } 一旦完成,NGINX將此處理為WebSocket連線。
NGINX Websocket示例
這是一個現場示例,顯示NGINX作為WebSocket代理。此示例使用ws,一種基於Node.js的WebSocket實現。NGINX作為使用ws和Node.js的簡單WebSocket應用程式的反向代理。這些說明已經通過Ubuntu 13.10和CentOS 6.5進行了測試,但可能需要針對其他作業系統和版本進行調整。對於此示例,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安裝nodejs在Ubuntu和nodeCentOS上。本例使用node,所以在Ubuntu上,我們需要從建立符號連結nodejs到node:
ln−s/usr/bin/nodejs/usr/local/bin/node要安裝ws,請執行以下命令:ln−s/usr/bin/nodejs/usr/local/bin/node要安裝ws,請執行以下命令: sudo npm install ws 注意:如果您收到錯誤訊息:“錯誤:無法從登錄檔中獲取: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 伺服器列印初始”Server started”訊息,然後在埠8010上偵聽,等待客戶端連線到它。當它收到一個客戶端請求時,它迴應它,併發送一個訊息回到客戶端包含它收到的訊息。要使NGINX代理這些請求,我們建立以下配置:
http { map httpupgradehttpupgradeconnection_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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
} 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 Server started
wscat --connect ws://192.168.100.20:8020
- 1
Connected (press CTRL+C to quit)
Hello Received from client: Hello < Server received from client: Hello 在這裡,我們看到客戶端和伺服器能夠通過作為代理的NGINX進行通訊,並且訊息可以繼續來回傳送,直到客戶端或伺服器斷開連線。讓NGINX正確處理WebSocket所需要的是正確設定標頭檔案來處理將連線從HTTP升級到WebSocket的升級請求。