nginx 配置websocket負載均衡

nginx會話保持

1.IP_hash

           在http下增加如下配置,確保nginx能處理正常的http請求,由於一般情況下開發人員在開發過程中會將websocket的會話狀態session通過集合進行管理存儲於內存中,則在多節點分佈式的情況下,可使用IP_HASH負載策略進行負載解決session不一致的問題。

ip_hash使用源地址哈希算法,將同一客戶端的請求總是發往同一個後端服務器,除非該服務器不可用。
http{
  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }
  upstream websocket {
    ip_hash;
    server 172.17.15.86:8723 weight=2; 
    server 172.17.15.85:8723 weight=2;
  }

ip_hash簡單易用,但有如下問題:
當後端服務器宕機後,session會丟失;
來自同一局域網的客戶端會被轉發到同一個後端服務器,可能導致負載失衡;
不適用於CDN網絡,不適用於前段還有代理的情況。

以下配置是在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

這兩個字段表示請求服務器升級協議爲WebSocket。服務器處理完請求後,響應如下報文:
# 狀態碼爲101

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade

告訴客戶端已成功切換協議,升級爲Websocket協議。握手成功之後,服務器端和客戶端便角色對等,就像普通的Socket一樣,能夠雙向通信。不再進行HTTP的交互,而是開始WebSocket的數據幀協議實現數據交換。

這裏使用map指令可以將變量組合成爲新的變量,會根據客戶端傳來的連接中是否帶有Upgrade頭來決定是否給源站傳遞Connection頭,這樣做的方法比直接全部傳遞upgrade更加優雅。

默認情況下,連接將會在無數據傳輸60秒後關閉,proxy_read_timeout參數可以延長這個時間或者源站通過定期發送ping幀以保持連接並確認連接是否還在使用。

2. sticky_cookie_insert

         使用sticky_cookie_insert啓用會話親緣關係,這會導致來自同一客戶端的請求被傳遞到一組服務器在同一臺服務器。與ip_hash不同之處在於,它不是基於IP來判斷客戶端的,而是基於cookie來判斷。因此可以避免上述ip_hash中來自同一局域網的客戶端和前段代理導致負載失衡的情況。

語法:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}

說明:
expires:設置瀏覽器中保持cookie的時間
domain:定義cookie的域
path:爲cookie定義路徑

使用後端服務器自身通過相關機制保持session同步,如:使用數據庫、redis、memcached等做session複製

參考:

https://blog.csdn.net/bigtree_3721/article/details/80906133
https://blog.csdn.net/weixin_34368949/article/details/92445435

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章