一個支援高網絡吞吐量、基于機器性能評分的TCP負載均衡器gobalan
作者最近用golang實作了一個TCP負載均衡器,靈感來自grpc。幾個主要的特性就是:
- 支援高網絡吞吐量
- 實作了基于機器性能評分來配置設定worker節點的負載均衡算法
- 盡量做到薄用戶端,降低用戶端複雜性
背景
先介紹幾種常用的負載均衡機制,以下幾種負載均衡方案介紹來自
grpc服務發現&負載均衡根據負載均衡實作所在的位置不同,通常可分為以下四種解決方案:
集中式LB(Proxy Model)

在服務消費者和服務提供者之間有一個獨立的LB,通常是專門的硬體裝置如 F5,或者基于軟體如 LVS,HAproxy等實作。LB上有所有服務的位址映射表,通常由運維配置注冊,當服務消費方調用某個目标服務時,它向LB發起請求,由LB以某種政策,比如輪詢(Round-Robin)做負載均衡後将請求轉發到目标服務。LB一般具備健康檢查能力,能自動摘除不健康的服務執行個體。 該方案主要問題:
單點問題,所有服務調用流量都經過LB,當服務數量和調用量大的時候,LB容易成為瓶頸,且一旦LB發生故障影響整個系統;
服務消費方、提供方之間增加了一級,有一定性能開銷。
程序内LB(Balancing-aware Client)
針對第一個方案的不足,此方案将LB的功能內建到服務消費方程序裡,也被稱為軟負載或者用戶端負載方案。服務提供方啟動時,首先将服務位址注冊到服務系統資料庫,同時定期報心跳到服務系統資料庫以表明服務的存活狀态,相當于健康檢查,服務消費方要通路某個服務時,它通過内置的LB元件向服務系統資料庫查詢,同時緩存并定期重新整理目标服務位址清單,然後以某種負載均衡政策選擇一個目标服務位址,最後向目标服務發起請求。LB和服務發現能力被分散到每一個服務消費者的程序内部,同時服務消費方和服務提供方之間是直接調用,沒有額外開銷,性能比較好。該方案主要問題:
開發成本,該方案将服務調用方內建到用戶端的程序裡頭,如果有多種不同的語言棧,就要配合開發多種不同的用戶端,有一定的研發和維護成本;
另外生産環境中,後續如果要對客戶庫進行更新,勢必要求服務調用方修改代碼并重新釋出,更新較複雜。
獨立程序LB(External LB service)
該方案是針對第二種方案的不足而提出的一種折中方案,原理和第二種方案基本類似。
不同之處是将LB和服務發現功能從程序内移出來,變成主機上的一個獨立程序。主機上的一個或者多個服務要通路目标服務時,他們都通過同一主機上的獨立LB程序做服務發現和負載均衡。該方案也是一種分布式方案沒有單點問題,一個LB程序挂了隻影響該主機上的服務調用方,服務調用方和LB之間是程序内調用性能好,同時該方案還簡化了服務調用方,不需要為不同語言開發客戶庫,LB的更新不需要服務調用方改代碼。
該方案主要問題:部署較複雜,環節多,出錯調試排查問題不友善。
gRPC服務發現及負載均衡設計
gRPC開源元件官方并未直接提供服務注冊與發現的功能實作,但其設計文檔已提供實作的思路,并在不同語言的gRPC代碼API中已提供了命名解析和負載均衡接口供擴充。
其基本實作原理:
服務啟動後gRPC用戶端向命名伺服器發出名稱解析請求,名稱将解析為一個或多個IP位址,每個IP位址标示它是伺服器位址還是負載均衡器位址,以及标示要使用那個用戶端負載均衡政策或服務配置。
用戶端執行個體化負載均衡政策,如果解析傳回的位址是負載均衡器位址,則用戶端将使用grpclb政策,否則用戶端使用服務配置請求的負載均衡政策。
負載均衡政策為每個伺服器位址建立一個子通道(channel)。
當有rpc請求時,負載均衡政策決定那個子通道即grpc伺服器将接收請求,當可用伺服器為空時用戶端的請求将被阻塞。
優缺點分析
可以看到第一種負載均衡是在server端進行負載均衡(也叫Proxy負載均衡),第二種和第三種負載均衡方案都是在用戶端進行的負載均衡,這兩類負載均衡各有優缺點
Proxy負載均衡優缺點
優點
-
隐藏後端伺服器。
反向代理能夠隐藏後端伺服器,所有浏覽器都不會與後端伺服器直接互動,進而能夠確定排程者的控制權,提升叢集的整體性能。
-
故障轉移
反向代理能夠更快速地移除故障結點。當監控程式發現某一後端伺服器出現故障時,能夠及時通知反向代理伺服器,并立即将其删除。
-
合理配置設定任務
但反向代理伺服器支援手動設定每台後端伺服器的權重。我們可以根據伺服器的配置設定不同的權重,權重的不同會導緻被排程者選中的機率的不同。
缺點
-
排程者壓力過大
由于所有的請求都先由反向代理伺服器處理,那麼當請求量超過排程伺服器的最大負載時,排程伺服器的吞吐率降低會直接降低叢集的整體性能。
-
制約擴充
當後端伺服器也無法滿足巨大的吞吐量時,就需要增加後端伺服器的數量,可沒辦法無限量地增加,因為會受到排程伺服器的最大吞吐量的制約。
用戶端負載均衡優缺點
- 用戶端和提供服務的伺服器進行直連,沒有了Proxy負載均衡器的瓶頸,并且容易擴充。
- 用戶端邏輯會變得複雜,它需要追蹤服務端的機器負載和健康度,需要實作負載均衡算法。第二種負載均衡機制還依賴用戶端的實作語言,需要為不同語言實作不同的負載均衡版本。
- 用戶端必須是受信任的,因為用戶端能夠拿到所有負載均衡節點的資訊。
grpc負載均衡優缺點
grpc負載均衡是上述兩種負載均衡機制的結合體,通過添加一個額外的load balancer server來實作,它基本上避免了兩種負載均衡機制的缺點。
- 負載均衡節點健康度檢查和機器負載通過這個load balancer server來實作,并且複雜的負載均衡算法都由其來實作,避免了用戶端過于複雜的缺點,用戶端隻是實作一些簡單的負載均衡算法。
- 服務網絡連接配接依然采用直連,繞過load balancer,解決了網絡吞吐量的問題。
- 用戶端仍然是需要受信任的
gobalan
為什麼要實作一個負載均衡器,因為目前為止沒有找到滿足作者要求的負載均衡器。市面上負載均衡器大多是proxy負載均衡器,像LVS,Haproxy,上行流量會成為它們的瓶頸。grpc的負載均衡隻是做了設計,并沒有實作,并且grpc負載均衡設計的初衷是per-call的,設計的目标應該是針對微服務中的API調用,并且感覺grpc負載均衡設計還有改進的空間。
gobalan有一下特點:
- gobalan是per-connection的,也就是一次TCP連接配接請求做一次負載均衡。
- gobalan所有負載均衡邏輯均在負載均衡器中實作,包括服務健康檢查,機器負載資訊收集,負載均衡算法的實作。
- 用戶端隻需要實作服務節點的請求和傳回值解析兩個邏輯就能使用gobalan,我們需要的是超薄用戶端。
- 用戶端和服務節點采用直連,避免了proxy負載均衡的網絡帶寬瓶頸。
整個系統的互動流程是下面這個樣子:
關于gobalan的更加詳細的設計原理和使用方法,參考
項目位址