WebSocket連線的負載均衡
本文由碼農網 – 郝林偉原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
當管理大系統時,負載均衡的問題一直是一個熱點話題。負載均衡的目的是最優化資源使用,最大化吞吐量,最小化響應時間,避免任何單一資源的過載,因而解決這個問題對效能表現是很關鍵的。在本文中我們將看一看針對這個問題的一些解決方法。
為了更好的理解WS負載均衡,讓我們深入瞭解一下TCP套接字的背景知識。預設地,一個單獨的伺服器可以處理65536個套接字連線,因為65536是可用的最大的TCP埠數。因此,既然WS連線擁有TCP的特性,每個WS客戶端佔用一個埠,我們可以肯定地說WebSocket的連線數目也是有限的。
事實上,這隻說對了一半。對每個單獨的IP地址,伺服器都可以處理65536個套接字。因而通過向伺服器上新增額外的網路介面,就很容易擴充套件那個數量。與此同時,去追蹤伺服器上現有多少連結是極其重要的。一旦超出了限制範圍,你會遇到很多關於TCP連線的問題(例如,此時不可能通過ssh去連線到一個伺服器)。因而,在你的應用程式程式碼中限制每個節點的WS連線數是很好的主意。當我們處理WebSockets問題時也會在我們的apps中使用一樣的思路。
一旦我們理解了主要的限制條件,以及解決方式之後,讓我們開始考慮負載均衡。下面我將描述在我們自己的專案中試過的三種方式。請注意所有的系統部分都是部署在AWS上的,其中的一些技巧和提示只適用於Amazon配置。
ELB方法
實現負載均衡最簡單的辦法是直接使用AWS提供的Elastic Load Balancer方法。從ELB切換到TCP模式是很容易的,這就使得任何型別的TCP連線的負載均衡成為可能, 包括WebSockets。這個方法有如下特性:
- LB的自動故障恢復;
- 負載均衡節點的自動伸縮;
- 非常簡單的設定。
基本上,對大多數情況而言它是一個很好的解決方案,在你遇到負載飛濺的增長情況之前。在這種情況下,ELB執行的很慢以至於無法建立新的連線。可以去聯絡Amazon,告訴他們去“預熱(pre-warm)”ELB,但是它對我們不是一個好的選項,基於負載測試的目的,當我們需要快速建立成千上萬的WS連線時;對客戶也不是好選項,基於系統的可用性。
軟體負載均衡器
我們曾經試過使用HAProxy作為一個負載均衡器。但是為了使HAProxy正確工作我們需要考慮上文討論的埠限制問題。為了使HAProxy能夠處理超過65536個連結,我們需要執行下面步驟:
1.建立一堆私有的IP地址。為了實現這個目的,選擇Amazon Instance -> Actions -> Networking -> Manage Private IP Addresses,我們新增三個IP地址:192.168.1.1,192.168.1.2,192.168.1.3。切記,IP要處於與你的真實應用程式伺服器同樣的子網中;
2.使用SSH連線到你的HAProxy例項,執行下面的命令:
$> ifconfig eth0:1 192.168.1.1 $> ifconfig eth0:2 192.168.1.2 $> ifconfig eth0:3 192.168.1.3
這些命令會往例項中新增3個虛擬網路介面;
3.配置HAProxy。這裡是haproxy.cfg檔案中的一段,用於3個Erlang節點接收WS連線。
listen erlang_front :8888 mode http balance roundrobin timeout connect 1s timeout queue 5s timeout server 3600s option httpclose option forwardfor server erlang-1 192.168.0.1:8888 source 192.168.1.1 server erlang-2 192.168.0.2:8888 source 192.168.1.2 server erlang-3 192.168.0.3:8888 source 192.168.1.3
現在,HAProxy能夠處理超過65536個WebSockets連結,通過增加虛擬網路介面,連線限制可以簡單地增長。同時,它也能非常快地建立新連線。這個方法看上去可行,儘管它有如下缺點:
- 故障恢復的HAProxy例項需要使用類似Keepalived工具去手動建立;
- 每次你增加一個新的Erlang節點,都要做些操作去重新配置HAProxy;
- 隨著連線數目增長,沒有能水平伸縮HAProxy的選項。我們只有一個垂直選項可用,因此當我們有了越來越多的線上使用者後,我們需要越來越多的昂貴的HAProxy例項(以及HAProxy映象節點)。
對這些缺點我們也還覺得滿意,但是一個更簡單的方案已經被實現了。那是可能的,因為我們已經有了一些實現好的程式碼,而我們的系統設計也允許我們使用一個定製方法。
定製方法
在繼續前進之前,我們先回顧一下下面的圖,它顯示了我們系統的架構。
我們擁有一個JavaScript客戶端應用程式,一個auth應用負責使用者授權,一個Erlang應用實現主要的功能。資料流如下:
1.客戶端生成一個含有憑證的HTTP請求,傳送給Auth Application;
2.Auth Application檢查憑證,生成一個令牌,以一種HTTP請求的形式將它傳送給Erlang Cluster;
3.Erlang應用確認,令牌已經收到,給Auth應用返回一個包含配置資訊的HTTP響應;
4.Auth App給客戶端應用程式傳送一個HTTP響應。響應中包含生成的令牌;
5.客戶端使用令牌通過我們的HAProxy負載均衡器建立與Erlang應用之間的WebSocket連線。
這是我們基本的資料流,它被稍微修改了一點。我們新增一個簡單的模組到Erlang應用程式中去追蹤每個Erlang節點上的WebSocket連線數。基於Erlang“分散式的”特性,每個節點可以知道其它節點的連線數。因而,我們可以選擇一個擁有更少連線的節點,我們使用這個節點的公共IP地址,把它傳送回那個auth應用程式。然後那個auth應用程式將這個IP地址隨令牌返回到客戶端。客戶端使用接收到的IP地址和令牌去建立連線。因而,最終的圖顯示如下:
現在我們能夠:
- 去掉WS負載均衡器,這就使得我們的系統變得不是那麼複雜;
- 新增Erlang節點,而不用對系統其它部分進行重新配置。
除此之外:
- 現在WS連線是平均分佈於Erlang節點之間的;
- 系統很容易水平伸縮;
- 對Erlang節點我們不需要使用Elastic IPs。
譯文連結:http://www.codeceo.com/article/websocket-load-balanced.html
英文原文:Load Balancing of WebSocket Connections
翻譯作者:碼農網 – 郝林偉
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- WebSocket負載均衡Web負載
- WEBLOGIC連線OracleRAC的負載均衡測試(轉載)WebOracle負載
- 負載均衡負載
- gRPC負載均衡(客戶端負載均衡)RPC負載客戶端
- gRPC負載均衡(自定義負載均衡策略)RPC負載
- 負載均衡的迷惑負載
- LVS負載均衡下session共享的實現方式-持久化連線負載Session持久化
- NGINX 負載均衡Nginx負載
- IP負載均衡負載
- 【Nginx】負載均衡Nginx負載
- nginx負載均衡Nginx負載
- 負載均衡的種類負載
- 4.8 負載均衡的概念負載
- 負載均衡原理的解析負載
- 負載均衡的那些事?負載
- 配置IIS的負載均衡負載
- [zt] RAC的負載均衡負載
- gRPC的負載均衡RPC負載
- 負載均衡技術(一)———負載均衡技術介紹負載
- 解密負載均衡技術和負載均衡演算法解密負載演算法
- websocket連線Web
- 負載均衡技術(二)———常用負載均衡服務介紹負載
- 【知識分享】四層負載均衡和七層負載均衡負載
- 淺談負載均衡負載
- 漫談負載均衡負載
- Nginx負載均衡模式Nginx負載模式
- 面試之負載均衡面試負載
- 負載均衡知多少?負載
- 負載均衡簡介負載
- 負載均衡詳解負載
- LoadBalancer負載均衡負載
- 負載均衡叢集負載
- 負載均衡---ribbon負載
- Nginx--負載均衡Nginx負載
- Flume負載均衡配置負載
- apache 負載均衡配置Apache負載
- 【Haproxy】haproxy負載均衡負載
- Tengine TCP 負載均衡TCP負載