《配置Nginx反向代理WebSocket》要點:
本文介紹了配置Nginx反向代理WebSocket,希望對您有用。如果有疑問,可以聯(lián)系我們。
題圖:By Anubhav Saxena?From Unsplash
用Nginx給網(wǎng)站做反向代理和負載均衡是廣泛使用的一種Web服務器部署技術.不僅能夠保證后端服務器的隱蔽性,還可以提高網(wǎng)站部署靈活性.
今天我們來講一下,如何用Nginx給WebSocket服務器實現(xiàn)反向代理和負載均衡.
WebSocket協(xié)議相比較于HTTP協(xié)議成功握手后可以多次進行通訊,直到連接被關閉.但是WebSocket中的握手和HTTP中的握手兼容,它使用HTTP中的Upgrade協(xié)議頭將連接從HTTP升級到WebSocket.這使得WebSocket程序可以更容易的使用現(xiàn)已存在的基礎設施.
WebSocket工作在HTTP的80和443端口并使用前綴ws://
或者wss://
進行協(xié)議標注,在建立連接時使用HTTP/1.1的101狀態(tài)碼進行協(xié)議切換,當前標準不支持兩個客戶端之間不借助HTTP直接建立Websocket連接.
更多Websocket的介紹可參考「WebSocket教程」一文.
Nginx在官方博客上給出了一個實踐樣例「Using Nginx as a Websocket Proxy」,我們以這個例子來演示W(wǎng)ebSocket的交互過程.
這個例子中將會使用到nodejs的一個WebSocket的ws模塊.
$ apt-get install nodejs npm
$ yum install nodejs npm
在Ubuntu上創(chuàng)建一個名叫node軟鏈.Centos默認為node,不用在單獨創(chuàng)建了.
# 如果不創(chuàng)建,后面運行wscat時Ubuntu環(huán)境中會報錯. $ ln -s /usr/bin/nodejs /usr/bin/node
ws
是nodejs的WebSocket實現(xiàn),我們借助它來搭建簡單的WebSocket Echo Server.wscat
是一個可執(zhí)行的WebSocket客戶端,用來調(diào)試WebSocket服務是否正常.
$ npm install ws wscat
如果訪問官方倉庫比較慢的話,可用淘寶提供的鏡像服務.
$ npm –registry=https://registry.npm.taobao.org install ws wscat
這個簡單的服務端實現(xiàn)的是向客戶端返回客戶端發(fā)送的消息.
$ vim 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); ? ?}); });
運行這個簡單的echo
服務
$ node server.js Server started
驗證服務端是否正常啟動
$ netstat ?-tlunp|grep 8010 tcp6 ? ? ? 0 ? ? ?0 :::8010 ? ? ? ? ? ? ? ? :::* ? ? ? ? ? ? ? ? ? ?LISTEN ? ? ?23864/nodejs
wscat
命令默認安裝當前用戶目錄node_modules/wscat/
目錄,我這里的位置是/root/node_modules/wscat/bin/wscat
.
輸入任意內(nèi)容進行測試,得到相同返回則說明運行正常.
$ cd /root/node_modules/wscat/bin/ $ ./wscat –connect ws://127.0.0.1:8010 connected (press CTRL+C to quit) > Hello < Server received from client: Hello > Welcome to www.hi-linux.com < Server received from client: Welcome to www.hi-linux.com
Nginx從1.3.13版本就開始支持WebSocket了,并且可以為WebSocket應用程序做反向代理和負載均衡.這里Nginx選用1.9.2版本.
$ cd /root $ wget ‘http://nginx.org/download/nginx-1.9.2.tar.gz’
$ apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make build-essential $ tar xzvf nginx-1.9.2.tar.gz $ cd nginx-1.9.2 $ ./configure $ make && make install
$ vim /usr/local/nginx/conf/nginx.conf # 在http上下文中增加如下配置,確保Nginx能處理正常http請求. http{ ?map $http_upgrade $connection_upgrade { ? ?default upgrade; ? ?” ? ? ?close; ?} ?upstream websocket { ? ?#ip_hash; ? ?server localhost:8010; ? ? ?server localhost:8011; ?} # 以下配置是在server上下文中添加,location指用于websocket連接的path. ?server { ? ?listen ? ? ? 80; ? ?server_name localhost; ? ?access_log /var/log/nginx/yourdomain.log; ? ?location / { ? ? ?proxy_pass http://websocket; ? ? ?proxy_read_timeout 300s; ? ? ?proxy_set_header Host $host; ? ? ?proxy_set_header X-Real-IP $remote_addr; ? ? ?proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ? ? ?proxy_http_version 1.1; ? ? ?proxy_set_header Upgrade $http_upgrade; ? ? ?proxy_set_header Connection $connection_upgrade; ? ? ? ?} ? ?} }
最重要的就是在反向代理的配置中增加了如下兩行,其它的部分和普通的HTTP反向代理沒有任何差別.
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
這里面的關鍵部分在于HTTP的請求中多了如下頭部:
Upgrade: websocket Connection: Upgrade
這兩個字段表示請求服務器升級協(xié)議為WebSocket.服務器處理完請求后,響應如下報文:
# 狀態(tài)碼為101 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: upgrade
告訴客戶端已成功切換協(xié)議,升級為Websocket協(xié)議.握手成功之后,服務器端和客戶端便角色對等,就像普通的Socket一樣,能夠雙向通信.不再進行HTTP的交互,而是開始WebSocket的數(shù)據(jù)幀協(xié)議實現(xiàn)數(shù)據(jù)交換.
這里使用map
指令可以將變量組合成為新的變量,會根據(jù)客戶端傳來的連接中是否帶有Upgrade頭來決定是否給源站傳遞Connection頭,這樣做的方法比直接全部傳遞upgrade更加優(yōu)雅.
默認情況下,連接將會在無數(shù)據(jù)傳輸60秒后關閉,proxy_read_timeout
參數(shù)可以延長這個時間或者源站通過定期發(fā)送ping幀以保持連接并確認連接是否還在使用.
Nginx會默認安裝到/usr/local/nginx
目錄下.
$ cd /usr/local/nginx/sbin $ ./nginx -c /usr/local/nginx/conf/nginx.conf
如果你想以Systemd服務的方式更方便的管理Nginx,可參考「基于Upsync模塊實現(xiàn)Nginx動態(tài)配置」 一文.
上面的配置會使NGINX監(jiān)聽80端口,并把接收到的任何請求傳遞給后端的WebSocket服務器.我們可以使用wscat
作為客戶端來測試一下:
$ cd /root/node_modules/wscat/bin/ $ ./wscat –connect ws://192.168.2.210 connected (press CTRL+C to quit) > Hello Nginx < Server received from client: Hello Nginx > Welcome to www.hi-linux.com < Server received from client: Welcome to www.hi-linux.com
WebSocket是端對端的,所以當一個代理服務器從客戶端攔截一個Upgrade請求,它需要去發(fā)送它自己的Upgrade請求到后端服務器,也包括合適的頭.
因為WebSocket是一個長連接,不像HTTP那樣是典型的短連接,所以反向代理服務器需要允許連接保持著打開,而不是在它們看起來空閑時就將它們關閉.
http://www.google.com
http://t.cn/RaTxJl9
https://github.com/animetosho/Nyuu/issues/14
https://www.nginx.com/blog/websocket-nginx/
https://www.starduster.me/2016/08/23/brief-talk-of-websocket/
文章來自微信公眾號:運維之美
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/4105.html