如何搭建應(yīng)對(duì)億級(jí)流量的高可用負(fù)載均衡?
上周分享的一篇《僅需這一篇,吃透「負(fù)載均衡」妥妥的》相信大家看完后對(duì)負(fù)載均衡的策略有了一些了解。這篇主要闡述負(fù)載均衡在實(shí)施的時(shí)候一些主流的解決方案。
為什么沒有 DNS?
再翻出第一篇中放出的一張圖來回顧一下。
之前也有小伙伴問到,為什么沒有列出 DNS?我認(rèn)為,DNS 的本質(zhì)是解決「domain name --> ip」的問題。
雖然 DNS 除了在公網(wǎng)運(yùn)用的之外,還會(huì)運(yùn)用于做內(nèi)網(wǎng)的自定義 domain name 解析,但是在程序里單靠它來做負(fù)載均衡的話,還是太勉強(qiáng)了。
當(dāng)然,基于 DNS 的“智能解析”功能可以做到 IP 的動(dòng)態(tài)返回,也算起到了負(fù)載均衡的作用。
但是,由于其本身是一個(gè)工作在 L3(網(wǎng)絡(luò)層)的解決方案,所以無法對(duì)“端口”進(jìn)行工作。
而一般我們程序之間的通訊很多都會(huì)涉及到端口,因此我們本篇先不討論 DNS。
如何實(shí)施?
在清楚了我們應(yīng)該在哪些環(huán)節(jié)考慮做負(fù)載均衡之后,接下去就是思考如何能夠循序漸進(jìn)的進(jìn)行。
古時(shí)候軍隊(duì)打仗的時(shí)候一般都是拿盾的扛在前面,頂住攻擊。而負(fù)載均衡解決方案從某種角度來說也是一個(gè)類似盾一般的防御性設(shè)施,因?yàn)榍疤峋褪且艹休d上游過來的流量。
因此,越往“前”做負(fù)載均衡解決方案,效果肯定會(huì)越好,因?yàn)槭鼙Wo(hù)的應(yīng)用范圍越廣。
如果說,系統(tǒng)之前沒有運(yùn)用過負(fù)載均衡,現(xiàn)在開始第一次做,該如何選擇呢?下面我根據(jù)心目當(dāng)中的優(yōu)先級(jí)來和大家聊一下。
硬件負(fù)載均衡
硬件這塊名氣最大的還屬 F5(根據(jù) ZOL 的數(shù)據(jù),其在市場(chǎng)占有率 51.44%),大大蓋過了其他幾家硬件商的風(fēng)頭。
此類硬件負(fù)載均衡器的特點(diǎn)是“壕”,畢竟是純商業(yè)化的東西,投入的資源和精力自然是眾多開源軟件負(fù)載均衡所無法比擬的,所以功能非常強(qiáng)大。
它們包含訪問加速、壓縮、安全等等負(fù)載均衡之外的許多附加功能。
題外話:如果用 F5 組網(wǎng)的話,有兩種結(jié)構(gòu),串行結(jié)構(gòu)和并行結(jié)構(gòu),也稱為直連模式和旁路模式。
前者的優(yōu)勢(shì)在對(duì)硬件產(chǎn)生壓力較小、且天然安全性高,而后者對(duì)原網(wǎng)絡(luò)架構(gòu)的改動(dòng)較小、且擴(kuò)展性較好。大家在實(shí)際的使用中結(jié)合自身情況來部署。
“壕”物能夠同時(shí)支持 L2~L7 的轉(zhuǎn)發(fā),所以上圖中的每一個(gè)標(biāo)注點(diǎn)都可以用硬件來做負(fù)載均衡。
因此,如果在經(jīng)濟(jì)允許的情況下,直接上 F5 能解決很多原本需要花更多時(shí)間去解決的問題。所以當(dāng)“時(shí)間”的重要度大于“金錢”的時(shí)候,建議優(yōu)先采用硬件方案。
軟件負(fù)載均衡(L7)

當(dāng)“金錢”的重要程度大于“時(shí)間”的時(shí)候,我們可以通過軟件來達(dá)到我們要的效果。相應(yīng)的,也增加了一些運(yùn)維成本。
一般情況下,只要對(duì)數(shù)據(jù)庫不濫用,往往我們從「單應(yīng)用 + 單庫」組合最先需要突破的是應(yīng)用,變成「多應(yīng)用 + 單庫」。
那么針對(duì) Web 應(yīng)用的 L7 負(fù)載均衡,比較主流的產(chǎn)品是 2 個(gè) Nginx、HAProxy。
在 L7 做負(fù)載均衡,最大的特點(diǎn)就是靈活,請(qǐng)求的 URL、Header 都是我們可以去掌控的,所以我們可以利用其中的任何信息為負(fù)載均衡策略所用。
這一類就是前面圖中的「反向代理」。作為「客戶端」和「Web 應(yīng)用」、「前端」和「后端」之間的橋梁。
實(shí)際操作中主要做兩步:
- 在公網(wǎng)的域名解析中,配置解析到「反向代理」。記錄類型是「A」,記錄值是「反向代理」的 IP。
- 配置真實(shí)提供服務(wù)的 Web 應(yīng)用 IP 和端口,和負(fù)載均衡策略。上圖中的配置是 Nginx 中的示例,負(fù)載均衡策略的缺省值是輪詢。
軟件負(fù)載均衡(L4)
當(dāng)「Web 應(yīng)用」所依賴的 TCP 協(xié)議的「服務(wù)」需要橫向擴(kuò)展,或者需要做「數(shù)據(jù)庫」、「分布式緩存」的多主、主從集群時(shí),那么就需要一個(gè)支持 L4 的負(fù)載均衡軟件。
這里最知名的就屬 LVS 了,1998 年 5 月由章文嵩博士建立,2004 年底被納入 Linux 內(nèi)核。
也正因?yàn)樗莾?nèi)核態(tài)的程序,所以相比用 Nginx、HAProxy 來做 L4 的負(fù)載均衡,在性能、資源的消耗上會(huì)更優(yōu)一些。
實(shí)際運(yùn)用中的操作步驟主要也是兩步:
- 在 LVS 中添加一個(gè) IP 虛擬服務(wù)(IPVS),并指定它的 IP、端口和負(fù)載均衡策略。
- 將 IP 虛擬服務(wù)關(guān)聯(lián)到真實(shí)的服務(wù)上,并指定模式和權(quán)重的信息。(做 L4 的負(fù)載均衡可以使用 NAT 或者 FULLNAT 模式)
題外話:LVS 的模式一共有四種,除了 NAT 和 FULLNAT(NAT 的增強(qiáng)版)模式外,它的 TUN 模式可以在 L3 做負(fù)載均衡,DR 模式可以在 L2 做負(fù)載均衡,到這個(gè)層面其實(shí)就和做硬件同處于一個(gè)層次了。
并且,隨著層次的深入,雖然對(duì)功能性上有所弱化,但是如果不考慮端口的話,單從 IP 層面的負(fù)載均衡來說,用 DR 模式做,則對(duì)數(shù)據(jù)包的加工介入度會(huì)降到最低,因此也是通過軟件做負(fù)載均衡能夠達(dá)到的性能極致。
另外,LVS 中運(yùn)用的虛擬 IP 概念,本質(zhì)上和 Nginx 中的“Server”概念一樣,定義了一個(gè)統(tǒng)一入口,作用上并沒有差別。
將 Nginx中的 upstream 關(guān)聯(lián)到 Server,就如 LVS 操作步驟第 2 點(diǎn)中的關(guān)聯(lián)一般。
這些每個(gè)具體的解決方案的使用教程網(wǎng)上比較多,就不展開了,大家實(shí)際用到的時(shí)候自行查閱一下,當(dāng)然盡量?jī)?yōu)先看官方的。
優(yōu)缺點(diǎn)
做了一個(gè)苦差事,把所有同類型的產(chǎn)品都整合了一下優(yōu)缺點(diǎn)和使用場(chǎng)景。不過,其中有不少是我沒用過的,所以僅供大家參考。
順手將一些網(wǎng)上到處充斥的一些過時(shí)結(jié)論做了更新,如:Nginx 不支持 Session Sticky 等。
我們可以看到,不同的解決方案有不同的側(cè)重點(diǎn)。因此在單個(gè)解決方案已經(jīng)無法滿足的情況下,我們可以組合使用,各盡所長(zhǎng)。
負(fù)載均衡這個(gè)領(lǐng)域還是以高可用和性能為兩個(gè)最重要因素,下面是我推薦的一種組合方式,也是在系統(tǒng)量級(jí)達(dá)到每小時(shí)上億 PV 之后最被廣泛使用的一種。
理論上,利用第一步 DNS 的域名解析所帶的負(fù)載均衡效果,只要復(fù)制多套 LVS 主備出來,綁上多個(gè)不同的虛 IP,可以做到無限橫向擴(kuò)展,以支撐不斷增長(zhǎng)的流量。
用到的 3 個(gè)軟件目前都是開源產(chǎn)品,LVS+Keepalived 負(fù)責(zé)做 Nginx 的負(fù)載均衡,而 Nginx 負(fù)責(zé)分發(fā)實(shí)際的請(qǐng)求到 HTTP 和 TCP 協(xié)議的應(yīng)用上。
關(guān)于 LVS 的模式選擇,如果在同網(wǎng)段內(nèi)的話優(yōu)先使用 DR 模式進(jìn)行 L2 轉(zhuǎn)發(fā),性能最好。否則使用 TUN 模式進(jìn)行 L3 分發(fā)。
與此同時(shí),在 L4、L7 的分發(fā)上使用 Nginx 來做,可以發(fā)揮其靈活易擴(kuò)展的特點(diǎn)以及其他的一些額外特性如緩存等,也算是物盡其用。
云時(shí)代,Service Mesh 風(fēng)興起。以 Sidecar 模式為核心的后起之秀 Linkerd、Conduit、NginMesh、Istio 等軟件除了滿足負(fù)載均衡之外,還為高可用相關(guān)的做了眾多的考量。
結(jié)語
有些事,并不需要做到一步到位,做技術(shù)也是這樣。其實(shí)大部分情況下,在以上方案中選擇一個(gè),做一層轉(zhuǎn)發(fā)就夠了。行遠(yuǎn)自邇,避免給自己添不必要的麻煩。