問題
一天更新完主分支後啓動nginx,結果報錯:nginx: [emerg] unknown "connection_upgrade" variable
解決方法
網上查,發現是nginx配置文件出了問題,將下面map代碼塊補上即可。
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location / {
#…
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
思考
雖然問題解決了,但後來我想知道爲什麼會出現這種情況,以及解決方法的真正原理。
在這篇博客可以知道問題出在了nginx代理websocket
上。
什麼是websocket
傳統的http通訊模式是:客戶端發起請求,服務端接收請求並作出響應。
而websocket協議複用了http的握手通道,具體指的是,客戶端通過HTTP請求與WebSocket服務端協商升級協議。
第一步,建立連接,客戶端使用http報文的格式發起協議升級的請求,服務端響應協議升級。
第二步,交換數據,客戶端與服務端可以使用websocket協議進行雙向通訊。
nginx反向代理websocket
首先,客戶端發起協議升級的請求,而nginx在攔截時需要識別出這是一個協議升級(upgrade)的請求,所以必須顯式設置升級(Upgrade head)和連接頭(Connection head),如下:
location /sockjs-node/ {
proxy_pass http://127.0.0.1:4200/sockjs-node/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
完成後,nginx將其作爲WebSocket連接處理。
接着,服務器響應升級請求,由nginx做代理進行處理,這時,需要進行如下配置:
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
}
}
這時就出現了一開始我所修改的地方,結合上面那段的內容,我大概可以猜出來map 代碼段該作用主要是根據客戶端請求中 $http_upgrade 的值,來構造改變 $connection_upgrade 的值,即根據變量 $http_upgrade 的值創建新的變量 $connection_upgrade。
由於我沒有進行map映射,它不知道connection_upgrade是什麼,所以就會出現unknown "connection_upgrade" variable
錯誤。
總結
即使是小小的一點改動,背後也會隱藏龐大的信息。如果止步於解決問題
,而不是探索問題
,就永遠不會有進步。
參考文檔:
https://www.nginx.com/blog/we...
https://www.cnblogs.com/chyin...