阿里云MVP乔帮主:五大类型负载均衡的原理场景详解(文末赠书)
?
喬幫主
讀完需要
21
分鐘速讀僅需 5 分鐘
導(dǎo)讀:本文摘自于阿里云 MVP、“喬幫主”喬銳杰所撰寫(xiě)的《阿里云運(yùn)維架構(gòu)實(shí)踐秘籍》一書(shū),我們發(fā)現(xiàn)常見(jiàn)負(fù)載均衡 LVS、Nginx、HAProxy、阿里云 SLB 及硬件負(fù)載均衡等,不同的負(fù)載均衡應(yīng)用場(chǎng)景和功能上有很大區(qū)別,這取決于負(fù)載均衡底層的原理,原理不同導(dǎo)致了不同負(fù)載均衡應(yīng)用場(chǎng)景、功能、性能的巨大差異。但萬(wàn)變不離其宗,這些常見(jiàn)負(fù)載均衡可以按照底層原理進(jìn)行歸類(lèi),相信通過(guò)本文內(nèi)容會(huì)讓你有很大收獲。
作者簡(jiǎn)介
? ?
喬銳杰 阿里云 MVP,江湖人稱(chēng)“喬幫主”,阿里云資深架構(gòu)師/技術(shù)專(zhuān)家。國(guó)內(nèi)云端架構(gòu)與運(yùn)維實(shí)踐開(kāi)拓者,曾主導(dǎo)過(guò)電商、金融、政府、視頻、游戲等領(lǐng)域千萬(wàn)級(jí)云端架構(gòu),在云端分布式集群架構(gòu)、云端運(yùn)維、云端安全等方面有著豐富的實(shí)戰(zhàn)經(jīng)驗(yàn)。擔(dān)任黑客講師/Java 高級(jí)講師/Python 講師/運(yùn)維高級(jí)講師/阿里云講師,從事過(guò)安全、研發(fā)、高級(jí)運(yùn)維、架構(gòu)師等大半個(gè)互聯(lián)網(wǎng)相關(guān)技術(shù)職位,現(xiàn)擔(dān)任駐云科技運(yùn)維總監(jiān)兼阿里云架構(gòu)師。
1
? ?
常見(jiàn)負(fù)載均衡的分類(lèi)
說(shuō)到常見(jiàn)負(fù)載均衡的分類(lèi),我們先來(lái)看看什么是 OSI 七層模型。我們常說(shuō)的二層/三層/四層交換機(jī),就是基于 OSI 七層模型所對(duì)應(yīng)的層來(lái)命名的。我剛開(kāi)始接觸網(wǎng)絡(luò)設(shè)備的時(shí)候,第一次聽(tīng)說(shuō)二層交換機(jī)、三層交換機(jī)時(shí),還以為交換機(jī)的硬件厚度有二層、有三層,后來(lái)才知道,其實(shí)是按照 OSI 七層模型來(lái)區(qū)別不同交換機(jī)的原理功能。OSI 七層模型主要作為一個(gè)通用模型來(lái)做理論分析,它是一個(gè)理論模型。而 TCP/IP 通信協(xié)議模型(四層)是互聯(lián)網(wǎng)的實(shí)際通信協(xié)議,兩者一般做映射對(duì)比及分析。
OSI 七層模型及對(duì)應(yīng)的傳輸協(xié)議
而常見(jiàn)的負(fù)載均衡有很多,有出名的硬件負(fù)載均衡,如 F5、Netscaler;還有常見(jiàn)開(kāi)源的負(fù)載均衡,比如 LVS、HAProxy、Nginx,甚至 Apache 也能做負(fù)載均衡(不推薦)。我們常說(shuō)的七層負(fù)載均衡、四層負(fù)載均衡,也是基于 OSI 七層模型的?;?OSI 七層模型的底層原理,我們把常見(jiàn)的負(fù)載均衡具體劃分為以下幾個(gè)類(lèi)型:二層、三層、四層、七層。最后再加上一個(gè)除 OSI 七層模型以外的 DNS,通過(guò) DNS 做負(fù)載均衡的場(chǎng)景也是非常常見(jiàn)的。
負(fù)載均衡的分類(lèi)
當(dāng)前二層、三層負(fù)載均衡的實(shí)現(xiàn)只有 LVS 能做到。而相比在四層、七層的負(fù)載均衡應(yīng)用得要更為廣泛,比如硬件負(fù)載均衡、Nginx、HAProxy 熱門(mén)的中間件都支持四層、七層的負(fù)載均衡。
2
? ?
負(fù)載均衡開(kāi)山鼻祖—LVS 的工作原理
前面已介紹了 LVS 的應(yīng)用場(chǎng)景及特性,但在介紹二層/三層/四層/七層負(fù)載均衡對(duì)比之前,有必要說(shuō)一下 LVS 的原理。在運(yùn)維領(lǐng)域,相信大家對(duì) LVS 并不陌生,幾乎提到負(fù)載均衡,提到運(yùn)維,都會(huì)提到 LVS。在實(shí)際負(fù)載均衡實(shí)踐應(yīng)用中,我看到了一些有意思的現(xiàn)象,接下來(lái)跟大家詳細(xì)分享一下相關(guān)的技術(shù)實(shí)踐。在此之前,先來(lái)看看負(fù)載均衡技術(shù)相關(guān)術(shù)語(yǔ)縮寫(xiě)。
負(fù)載均衡技術(shù)相關(guān)術(shù)語(yǔ)縮寫(xiě)
LVS 負(fù)載均衡技術(shù)的實(shí)現(xiàn),主要由 IPVS 和 Ipvsadm 實(shí)現(xiàn)。
IPVS:是 LVS 集群系統(tǒng)的核心部分,是基于 Linux Netfilter 框架實(shí)現(xiàn)的一個(gè)內(nèi)核模塊,主要工作于內(nèi)核空間的 INPUT 鏈上。其鉤子函數(shù)分別 HOOK 在 LOCAL_IN 和 FORWARD 兩個(gè) HOOK 點(diǎn)。
需要特別注意的是,IPVS 是直接作用在內(nèi)核空間進(jìn)行數(shù)據(jù)包的修改及轉(zhuǎn)發(fā)的。而 Nginx/HAProxy 作用在用戶(hù)空間,這使得 LVS 的性能更為強(qiáng)悍(能夠趕上硬件負(fù)載均衡的性能),而 Nginx/HAProxy 根本不是一個(gè)量級(jí)。并且現(xiàn)在 IPVS 已經(jīng)是 Linux 內(nèi)核標(biāo)準(zhǔn)的一部分,在早期的 Linux 系統(tǒng)版本中,安裝 LVS 還需要重新編譯內(nèi)核,當(dāng)然現(xiàn)在已經(jīng)不需要了。
內(nèi)核LVS數(shù)據(jù)包流向
Ipvsadm:而 Ipvsadm 是工作在用戶(hù)空間,主要用于用戶(hù)定義和管理集群服務(wù)的工具。所以實(shí)際在安裝配置 LVS 時(shí),主要是安裝配置 Ipvsadm。比如在 Redhat 中安裝一條簡(jiǎn)單命令來(lái)實(shí)現(xiàn):
yum install ipvsadm
LVS 原理架構(gòu)
在 Director Server 上,IPVS 虛擬出一個(gè)對(duì)外提供訪問(wèn)的 IP 地址,用戶(hù)必須通過(guò)這個(gè)虛擬的 VIP 地址訪問(wèn)服務(wù)器。由于 LVS 是采用 VIP(三層 IP 地址)作為請(qǐng)求入口的,這也是很多人喜歡把 LVS 統(tǒng)稱(chēng)為 IP 負(fù)載均衡的原因,即也是三層負(fù)載均衡。但 LVS 有 DR/IP TUN/NAT3 種模式,每種模式的核心原理分別作用在二層/三層/四層,所以把 LVS 稱(chēng)為二層/三層/四層負(fù)載均衡更為恰當(dāng)些。
具體數(shù)據(jù)包的走向如下:
訪問(wèn)請(qǐng)求首先經(jīng)過(guò) VIP 到達(dá)負(fù)載調(diào)度器的內(nèi)核空間。
PREROUTING 鏈在接收到用戶(hù)請(qǐng)求后,會(huì)判斷目標(biāo) IP,確定是本機(jī) IP,將數(shù)據(jù)包發(fā)往 INPUT 鏈。
當(dāng)用戶(hù)請(qǐng)求到達(dá) INPUT 時(shí),IPVS 會(huì)將用戶(hù)請(qǐng)求和 Ipvsadm 定義好的規(guī)則進(jìn)行對(duì)比。如果用戶(hù)請(qǐng)求的就是定義的集群服務(wù),那么此時(shí) IPVS 會(huì)強(qiáng)行修改數(shù)據(jù)包,并將新的數(shù)據(jù)包發(fā)往 POSTROUTING 鏈。
POSTROUTING 鏈接收數(shù)據(jù)包后發(fā)現(xiàn)目標(biāo) IP 地址剛好是自己的后端服務(wù)器,最終將數(shù)據(jù)包發(fā)送給后端的服務(wù)器。對(duì)于數(shù)據(jù)包的修改,基于修改方式的不同,形成了 LVS 的 3 種模式。
LVS 三種模式
3
? ?
二層負(fù)載均衡
當(dāng)前的負(fù)載均衡界,只有 LVS 實(shí)現(xiàn)了二層負(fù)載均衡。所以二層負(fù)載均衡實(shí)踐主要為 LVS 的 DR 模式實(shí)踐。
二層負(fù)載均衡數(shù)據(jù)包走向原理
以下是對(duì)二層負(fù)載均衡數(shù)據(jù)包走向原理的詳細(xì)說(shuō)明:
客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源地址是 CIP,目標(biāo)地址是 VIP。
負(fù)載均衡會(huì)將客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源 MAC 地址改為自己 DIP 的 MAC 地址,目標(biāo) MAC 改為了 RIP 的 MAC 地址,并將此包發(fā)送給后端服務(wù)器。這里要求所有后端服務(wù)器和負(fù)載均衡所在服務(wù)器只能在一個(gè) VLAN(局域網(wǎng))里面,即不能跨 VLAN。根據(jù)二層原理我們可以看到,在后端服務(wù)器中能直接獲取客戶(hù)端的源 IP 地址,netstat -n 能直接查看客戶(hù)端請(qǐng)求通信的源 IP。示例代碼如下:># netstat -nActive Internet connections (w/o servers)Proto Recv-Q Send-Q Local Address Foreign Address Statetcp 0 0 192.168.3.33:80 47.100.187.71:13537 ESTABLISHEDtcp 0 0 192.168.3.33:80 115.29.209.104:49435 ESTABLISHEDtcp 0 0 192.168.3.33:80 115.19.244.124:45418 TIME_WAITtcp 0 0 192.168.3.33:80 115.29.233.224:59310 ESTABLISHED
后端服務(wù)器發(fā)現(xiàn)請(qǐng)求數(shù)據(jù)包報(bào)文中的目的 MAC 是自己,會(huì)將數(shù)據(jù)包報(bào)文接收下來(lái)。由于數(shù)據(jù)包的 MAC 地址被修改,因此后端服務(wù)器需要在 lo 網(wǎng)口綁定 VIP,這樣數(shù)據(jù)包才會(huì)有“歸屬感”。處理完請(qǐng)求報(bào)文后,將響應(yīng)報(bào)文通過(guò) lo 接口送給 eth0 網(wǎng)卡直接發(fā)送給客戶(hù)端。由于數(shù)據(jù)包由后端服務(wù)器直接返回給客戶(hù)端,因此也會(huì)要求后端服務(wù)器必須綁定公網(wǎng) IP。
4
? ?
三層負(fù)載均衡
同樣,在當(dāng)前負(fù)載均衡界,只有 LVS 實(shí)現(xiàn)了三層負(fù)載均衡。所以三層負(fù)載均衡實(shí)踐主要為 LVS 的 IP-TUN 模式實(shí)踐。
三層負(fù)載均衡數(shù)據(jù)包走向原理
以下是對(duì)三層負(fù)載均衡數(shù)據(jù)包走向原理的詳細(xì)說(shuō)明:
客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源地址是 CIP,目標(biāo)地址是 VIP。
負(fù)載均衡將客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文首部再封裝一層 IP 報(bào)文,將源地址改為 DIP,目標(biāo)地址改為 RIP,并將此數(shù)據(jù)包發(fā)送給后端服務(wù)器。與二層負(fù)載均衡不同的是,包通信通過(guò) TUNNEL 模式實(shí)現(xiàn),因此不管是內(nèi)網(wǎng)還是外網(wǎng)都能通信,所以不需要 LVS VIP 與后端服務(wù)器在同一個(gè)網(wǎng)段內(nèi),即能跨 VLAN。但三層負(fù)載均衡原理導(dǎo)致在后端服務(wù)器中不能直接獲取客戶(hù)端的源 IP 地址,netstat -n 能查看到的是和負(fù)載均衡的通信 IP。示例代碼如下:># netstat -nActive Internet connections (w/o servers)Proto Recv-Q Send-Q Local Address Foreign Address Statetcp 0 0 192.168.3.33:80 172.16.2.2:13537 ESTABLISHEDtcp 0 0 192.168.3.33:80 172.16.2.2:49435 ESTABLISHEDtcp 0 0 192.168.3.33:80 172.16.2.2:45418 TIME_WAITtcp 0 0 192.168.3.33:80 172.16.2.2:59310 ESTABLISHED
云訣竅?
TUNNEL 模式走的隧道模式,運(yùn)維起來(lái)比較困難,在實(shí)際應(yīng)用中不常用。
后端服務(wù)器收到請(qǐng)求報(bào)文后,會(huì)首先拆開(kāi)第一層封裝,然后發(fā)現(xiàn)里面還有一層 IP 首部的目標(biāo)地址是自己 lo 接口上的 VIP,所以會(huì)處理次請(qǐng)求報(bào)文,并將響應(yīng)報(bào)文通過(guò) lo 接口發(fā)送給 eth0 網(wǎng)卡直接發(fā)送給客戶(hù)端。
5
? ?
四層負(fù)載均衡
LVS 的 NAT 模式、阿里云的四層 SLB、Nginx/HAProxy 的四層,雖然都是四層負(fù)載均衡,但是它們的底層原理有很大差異,這就導(dǎo)致它們的功能特性也有很大區(qū)別。
5.2
? ?
LVS-NAT 下的四層負(fù)載均衡
四層負(fù)載均衡 LVS-NAT 數(shù)據(jù)包走向原理如下圖所示。以下是對(duì)四層負(fù)載均衡 LVS-NAT 數(shù)據(jù)包走向原理的詳細(xì)說(shuō)明。
客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源地址是 CIP,目標(biāo)地址是 VIP。
負(fù)載均衡將客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的目標(biāo)地址改為 RIP 地址,并將此數(shù)據(jù)包發(fā)送給后端服務(wù)器。同樣要求所有的后端服務(wù)器和負(fù)載均衡所在服務(wù)器只能在一個(gè) VLAN(局域網(wǎng))里面,即不能跨 VLAN。同樣,根據(jù) LVS 的 NAT 模式修改數(shù)據(jù)包報(bào)文的原理,在后端服務(wù)器中能直接獲取客戶(hù)端的源 IP 地址,netstat -n 能直接查看客戶(hù)端請(qǐng)求通信的源 IP。
報(bào)文送到后端服務(wù)器后,目標(biāo)服務(wù)器會(huì)響應(yīng)該請(qǐng)求,并將響應(yīng)數(shù)據(jù)包報(bào)文返還給負(fù)載均衡。每臺(tái)內(nèi)部的后端服務(wù)器的網(wǎng)關(guān)地址必須是負(fù)載均衡所在服務(wù)器的內(nèi)網(wǎng)地址,即要配置 SNAT,這樣數(shù)據(jù)包才能經(jīng)過(guò) LVS 返回給客戶(hù)端。
然后負(fù)載均衡將此數(shù)據(jù)包報(bào)文的源地址修改為本機(jī)并發(fā)送給客戶(hù)端。
四層負(fù)載均衡 LVS-NAT 數(shù)據(jù)包走向原理
云訣竅
我們可以看到,目標(biāo)服務(wù)器處理完數(shù)據(jù)包返回給客戶(hù)端的時(shí)候,會(huì)經(jīng)過(guò) LVS,然后再把數(shù)據(jù)包回給客戶(hù)端。由此可以看到,LVS NAT 模式存在很大的性能瓶頸(就是在于 LVS 這一端),而相比于 DR 及 IP-TUN 模式,數(shù)據(jù)包后端服務(wù)器直接返回給客戶(hù)端就不存在這個(gè)問(wèn)題。在實(shí)際運(yùn)用中,我也遇到過(guò)這個(gè)真實(shí)的性能瓶頸案例。之前工作過(guò)的一家公司主要從事電商領(lǐng)域,在一年一度的雙十一備戰(zhàn)中,流量高峰期客戶(hù)端出現(xiàn)嚴(yán)重的卡頓、丟包和延時(shí)。當(dāng)時(shí)負(fù)載均衡采用的就是 LVS 的 NAT 模式,我們發(fā)現(xiàn)高并發(fā)高流量模式下,內(nèi)網(wǎng)的流量可達(dá)到千兆。那時(shí)緊急切換到 LVS DR 模式,故障很快消除了。
5.3
? ?
阿里云 SLB 下的四層負(fù)載均衡
阿里云四層負(fù)載均衡針對(duì) LVS 的一些問(wèn)題進(jìn)行了定制和優(yōu)化,新增轉(zhuǎn)發(fā)模式 FULLNAT。
阿里云四層負(fù)載均衡對(duì) LVS 的優(yōu)化
由此可見(jiàn)基于 LVS,阿里云四層負(fù)載均衡實(shí)現(xiàn)了跨 VLAN、具備防 DDoS 攻擊的能力、采用集群方式部署。這 3 個(gè)方面相比原生態(tài)的 LVS,功能上做了很大的改進(jìn)。
云訣竅
實(shí)踐應(yīng)用中,我們發(fā)現(xiàn)使用阿里云的四層負(fù)載均衡,數(shù)據(jù)包的走向跟后端的 ECS 有沒(méi)有綁定公網(wǎng) IP 有直接關(guān)系(僅限經(jīng)典網(wǎng)絡(luò))。
當(dāng)后端 ECS 不綁定公網(wǎng)的時(shí)候,負(fù)載均衡轉(zhuǎn)發(fā)數(shù)據(jù)包給后端 ECS。后端 ECS 處理完將返回?cái)?shù)據(jù)包給負(fù)載均衡,負(fù)載均衡再返回?cái)?shù)據(jù)包給客戶(hù)端。這種方式類(lèi)似 LVS 的 NAT 模式。
當(dāng)后端經(jīng)典網(wǎng)絡(luò)的 ECS 綁定公網(wǎng)的時(shí)候(只有經(jīng)典網(wǎng)絡(luò)的 ECS 綁定的公網(wǎng) IP 會(huì)單獨(dú)分配公網(wǎng)網(wǎng)卡 eth1),負(fù)載均衡轉(zhuǎn)發(fā)數(shù)據(jù)包給后端 ECS。后端 ECS 處理完將數(shù)據(jù)包直接通過(guò)公網(wǎng)網(wǎng)卡返回給客戶(hù)端。這種方式類(lèi)似 LVS 的 DR 模式。在 ECS 的公網(wǎng)網(wǎng)卡監(jiān)控中看不到這塊的流量明細(xì),這塊流量?jī)?nèi)容直接歸并到 SLB 中計(jì)算了。但我們通過(guò) Zabbix 相關(guān)監(jiān)控,可以看到 eth1 公網(wǎng)網(wǎng)卡流量,并能抓到相應(yīng)明細(xì)。有時(shí)候?qū)嶋H公網(wǎng)網(wǎng)卡流量甚至遠(yuǎn)遠(yuǎn)超過(guò)公網(wǎng)帶寬峰值,由此可以看到,這部分返回給客戶(hù)端的數(shù)據(jù)包走公網(wǎng)網(wǎng)卡,不受后端 ECS 綁定的公網(wǎng)帶寬限制,且不納入 ECS 的流量計(jì)費(fèi),單獨(dú)放在 SLB 流量計(jì)費(fèi)中了。
如果 ECS 有公網(wǎng) IP 和私網(wǎng) IP,禁用公網(wǎng)網(wǎng)卡就會(huì)影響負(fù)載均衡服務(wù),因?yàn)樵谟泄W(wǎng)網(wǎng)卡的情況下,默認(rèn)路由會(huì)走公網(wǎng),如禁用就無(wú)法回包,因此負(fù)載均衡服務(wù)會(huì)受影響。建議不要禁止,如一定要這么做,需要修改默認(rèn)路由為私網(wǎng)才會(huì)不影響服務(wù)。但需要考慮業(yè)務(wù)是否對(duì)公網(wǎng)有依賴(lài),如通過(guò)公網(wǎng)訪問(wèn) RDS 等。
7.1
? ?
Nginx/HAProxy 下的四層負(fù)載均衡
四層負(fù)載均衡 Nginx/HAProxy 數(shù)據(jù)包走向原理如下圖所示。以下是對(duì)四層負(fù)載均衡 Nginx/HAProxy 數(shù)據(jù)包走向原理的詳細(xì)說(shuō)明。
四層負(fù)載均衡 Nginx/HAProxy 數(shù)據(jù)包走向原理
云訣竅
需要重點(diǎn)注意的是,這里已經(jīng)跟 LVS 有本質(zhì)的區(qū)別。LVS 的 NAT 模式對(duì)外是以虛擬 VIP 作為請(qǐng)求入口(IP 層為三層),然后在三層負(fù)載均衡的基礎(chǔ)之上用 IP+PORT 接收請(qǐng)求,再轉(zhuǎn)發(fā)到對(duì)應(yīng)后端服務(wù)器,所以 LVS 的 NAT 模式是三層負(fù)載均衡+四層負(fù)載均衡。而 Nginx/HAProxy 的四層對(duì)外直接暴露的是 DIP+TCP/UDP IP 端口服務(wù)。
客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源地址是 CIP,訪問(wèn)目標(biāo)地址是 DIP+IP 端口。
負(fù)載均衡在用戶(hù)空間接收數(shù)據(jù)包,并且負(fù)載均衡和后端服務(wù)器發(fā)起新的 TCP 三次握手,建立新的 TCP 連接。所以這時(shí)候是負(fù)載均衡代替客戶(hù)端與后端發(fā)起新的 TCP 請(qǐng)求連接。請(qǐng)求數(shù)據(jù)包為一個(gè)新的請(qǐng)求數(shù)據(jù)包,報(bào)文的源地址是 DIP,目標(biāo)地址是 RIP。所以在后端服務(wù)器中,netstat -n 查看到的是和負(fù)載均衡的通信 IP。但負(fù)載均衡和后端服務(wù)器是建立新的 TCP 連接,所以后端服務(wù)器和負(fù)載均衡所在服務(wù)器可以進(jìn)行跨 VLAN(局域網(wǎng))通信。
報(bào)文發(fā)送到后端服務(wù)器后,服務(wù)器響應(yīng)該請(qǐng)求,并將響應(yīng)數(shù)據(jù)包報(bào)文返還給負(fù)載均衡。相比 LVS 的 NAT 模式,Nginx/HAProxy 下的四層負(fù)載均衡無(wú)須將每臺(tái)內(nèi)部的后端服務(wù)器的網(wǎng)關(guān)地址設(shè)為負(fù)載均衡所在服務(wù)器的內(nèi)網(wǎng)地址,即無(wú)須配置 SNAT。因?yàn)槭秦?fù)載均衡和后端服務(wù)器建立了新的 TCP 連接,不必?fù)?dān)心數(shù)據(jù)包不會(huì)返回給負(fù)載均衡。
然后負(fù)載均衡將此數(shù)據(jù)包報(bào)文的響應(yīng)內(nèi)容進(jìn)行重新打包并返回給客戶(hù)端。
6
? ?
七層負(fù)載均衡
在常見(jiàn)負(fù)載均衡分類(lèi)中,其實(shí)應(yīng)用最為廣泛的還是七層和四層負(fù)載均衡。而七層和四層負(fù)載均衡最主要的區(qū)別是,在七層負(fù)載均衡中能獲取用戶(hù)請(qǐng)求的 HTTP 頭信息。具體什么是 HTTP 頭信息,我們以 nginx.conf 配置中定義的 Nginx 日志文件的格式內(nèi)容從側(cè)面進(jìn)行說(shuō)明:
log_format '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
然后我們?cè)趯?duì)應(yīng)的日志文件中可以看到具體客戶(hù)端的請(qǐng)求頭內(nèi)容信息,如下:
45.127.220.171 - - [02/Dec/2018:14:10:17 +0800] "GET https://qiaobangzhu.cn ( https://qiaobangzhu.cn ) HTTP/1.1" 301 184 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
可以看到在七層負(fù)載均衡中,我們能獲取客戶(hù)端訪問(wèn)的 IP、HTTP 請(qǐng)求類(lèi)型(GET/POST)、訪問(wèn)的域名主機(jī)地址及請(qǐng)求的 URL 明細(xì)、瀏覽器的類(lèi)型等,這便是 HTTP 請(qǐng)求頭信息。而七層負(fù)載均衡的原理就是根據(jù) HTTP 請(qǐng)求頭來(lái)做判斷轉(zhuǎn)發(fā),在七層負(fù)載均衡中應(yīng)用最為廣泛的當(dāng)數(shù)虛擬主機(jī)功能。其實(shí)虛擬主機(jī)功能的核心就是獲取 HTTP 請(qǐng)求頭中的 HOST 字段來(lái)對(duì)應(yīng)匹配轉(zhuǎn)發(fā)。
七層負(fù)載均衡數(shù)據(jù)包走向原理
以下是對(duì)七層負(fù)載均衡數(shù)據(jù)包走向原理的詳細(xì)說(shuō)明。
和 Nginx/HAProxy 的四層一樣,客戶(hù)端請(qǐng)求數(shù)據(jù)包報(bào)文的源地址是 CIP。只不過(guò)在實(shí)際應(yīng)用中,這里訪問(wèn)的目標(biāo)地址并不是 DIP+IP 端口,而是 URL。
同樣和 Nginx/HAProxy 的四層一樣,負(fù)載均衡在用戶(hù)空間接收數(shù)據(jù)包,并且負(fù)載均衡和后端服務(wù)器發(fā)起新的 TCP 三次握手,建立新的 TCP 連接。所以這時(shí)候是負(fù)載均衡代替客戶(hù)端與后端發(fā)起新的 TCP 請(qǐng)求連接。請(qǐng)求數(shù)據(jù)包是新的,報(bào)文的源地址是 DIP,目標(biāo)地址是 RIP,并且還有客戶(hù)端請(qǐng)求的目標(biāo) URL(這里可以看到,對(duì)于七層負(fù)載均衡,目標(biāo)地址可能一直在變,但訪問(wèn)的目標(biāo) URL 始終不變,除非修改了客戶(hù)端請(qǐng)求內(nèi)容)。
報(bào)文送到后端服務(wù)器后,服務(wù)器響應(yīng)該請(qǐng)求,并將響應(yīng)數(shù)據(jù)包報(bào)文返還給負(fù)載均衡。跟 Nginx/HAProxy 一樣,這里無(wú)須額外配置后端服務(wù)器的網(wǎng)關(guān),即 SNAT 相關(guān)配置。
然后負(fù)載均衡將此數(shù)據(jù)包報(bào)文的響應(yīng)內(nèi)容進(jìn)行重新打包并返回給客戶(hù)端。
綜上所述,因?yàn)槠邔又心塬@取應(yīng)用層 HTTP 的請(qǐng)求內(nèi)容,所以七層負(fù)載均衡有如下常見(jiàn)應(yīng)用場(chǎng)景:
七層作用在 HTTP 應(yīng)用層,所以七層的負(fù)載均衡只能跟 Tomcat、PHP 等 Web 服務(wù)做負(fù)載均衡。
可以根據(jù)請(qǐng)求的域名來(lái)做轉(zhuǎn)發(fā)。比如請(qǐng)求者訪問(wèn) A 域名,轉(zhuǎn)發(fā)到后端 A 服務(wù)器;請(qǐng)求訪問(wèn) B 域名,轉(zhuǎn)發(fā)到后端 B 服務(wù)器。這個(gè)功能,在七層叫虛擬主機(jī)功能,是七層應(yīng)用中最為熱門(mén)的應(yīng)用實(shí)踐。
可以根據(jù)請(qǐng)求的 URL 來(lái)做轉(zhuǎn)發(fā)。比如請(qǐng)求者訪問(wèn)的 URL 包含 A 目錄,就轉(zhuǎn)發(fā)到 A 服務(wù)器;請(qǐng)求訪問(wèn)的 URL 包含 B 目錄,就轉(zhuǎn)發(fā)到 B 服務(wù)器。
可以根據(jù)請(qǐng)求的瀏覽器類(lèi)型來(lái)做轉(zhuǎn)發(fā)。比如請(qǐng)求者使用的瀏覽器類(lèi)型是 Chrome,就轉(zhuǎn)發(fā)到 A 服務(wù)器;請(qǐng)求者使用的瀏覽器類(lèi)型是 Firefox,就轉(zhuǎn)發(fā)到 B 服務(wù)器。
而四層只能獲取訪問(wèn)的目標(biāo)/源 IP 地址和端口。所以四層的負(fù)載均衡,單純地是將請(qǐng)求輪詢(xún)轉(zhuǎn)發(fā)到后端目標(biāo)服務(wù)器。并不能跟七層一樣,做相應(yīng)的邏輯判斷,然后最終再轉(zhuǎn)發(fā)給符合要求的后端目標(biāo)服務(wù)器。相比七層,四層的應(yīng)用場(chǎng)景包括:
對(duì) MySQL、LDAP、Redis、Memcache 等四層應(yīng)用做負(fù)載均衡。
對(duì)七層 HTTP 的 Web 類(lèi)應(yīng)用做負(fù)載均衡,如 Tomcat、PHP。
對(duì)七層 Nginx、HAProxy 的負(fù)載均衡做負(fù)載均衡(具體在實(shí)踐中,四層和七層怎么來(lái)搭配使用,詳見(jiàn)第二篇中負(fù)載均衡的相關(guān)章節(jié))。
但四層中沒(méi)辦法跟七層一樣,做虛擬主機(jī)的應(yīng)用。我曾經(jīng)在面試中問(wèn)過(guò)這個(gè)問(wèn)題,就是 LVS 能不能識(shí)別域名來(lái)做轉(zhuǎn)發(fā)。比如請(qǐng)求者訪問(wèn) A 域名,轉(zhuǎn)發(fā)到后端 A 服務(wù)器;請(qǐng)求訪問(wèn) B 域名,轉(zhuǎn)發(fā)到后端 B 服務(wù)器。有意思的是,有一些經(jīng)驗(yàn)豐富的運(yùn)維人員對(duì)這個(gè)問(wèn)題還回答不出來(lái),這就需要好好看一下底層原理和對(duì)應(yīng)負(fù)載均衡的應(yīng)用場(chǎng)景了。答案肯定是不行的,因?yàn)?LVS 在四層和二層,沒(méi)辦法識(shí)別封裝在七層中的數(shù)據(jù)包內(nèi)容。再舉個(gè)七層負(fù)載均衡實(shí)踐的例子,要訪問(wèn)我們駐云內(nèi)部的某個(gè)系統(tǒng),要求客戶(hù)端必須使用 Chrome 瀏覽器,可參考以下核心配置:
location / {if ( $http_user_agent !~ ^.Chrome/5|6. ){rewrite ^(.)$ https://qiaobangzhu.cn/error.html ( https://qiaobangzhu.cn/error.html ) permanent;}proxy_pass http://192.168.2.2:81/ ( http://192.168.2.2:81/ );proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
實(shí)現(xiàn)的核心配置就是獲取七層頭信息里面的數(shù)據(jù)來(lái)做對(duì)比判斷,如果符合,執(zhí)行對(duì)應(yīng)的操作即可。這個(gè)是四層/二層負(fù)載均衡無(wú)法實(shí)現(xiàn)的功能。
7
? ?
負(fù)載均衡的“一次連接”和“兩次連接”核心總結(jié)
7.2
? ?
LVS 二層/四層的“一次連接”
LVS 的 DR 模式、NAT 模式對(duì)數(shù)據(jù)包的處理都僅做“一次連接”,即負(fù)載均衡對(duì)數(shù)據(jù)包僅做轉(zhuǎn)發(fā)。
LVS 的三次握手?jǐn)?shù)據(jù)包走向
LVS 能夠做到“一次連接”的本質(zhì)原因是 LVS 工作在內(nèi)核空間。LVS3 種模式都是工作在內(nèi)核空間,數(shù)據(jù)包的處理也僅在內(nèi)核空間,這也是 LVS 輕量高效、高性能的最為本質(zhì)的原因。
云訣竅?
LVS 能夠做到“一次連接”,所以通過(guò)四層 SLB,我們能直接在后端服務(wù)器 ECS 中 netstat -n 查看到客戶(hù)端通信的源 IP 地址。
LVS 請(qǐng)求數(shù)據(jù)包走向
7.3
? ?
Nginx/HAProxy 四層的“二次連接”
相比于 LVS,Nginx/HAProxy 四層要建立“二次連接”。
Nginx/HAProxy 四層三次握手?jǐn)?shù)據(jù)包走向
客戶(hù)端在向負(fù)載均衡進(jìn)行 TCP 三次握手后,負(fù)載均衡會(huì)馬上發(fā)起新的 TCP 連接,即為“二次連接”。由于是負(fù)載均衡與后端建立新的 TCP 三次握手及轉(zhuǎn)發(fā)客戶(hù)端請(qǐng)求的數(shù)據(jù),所以在后端服務(wù)器 netstat -n 查看到的請(qǐng)求通信的 IP 是負(fù)載均衡的 IP。而相比于 LVS,Nginx/HAProxy 四層工作在用戶(hù)空間,對(duì)數(shù)據(jù)包的處理是在用戶(hù)空間完成的,數(shù)據(jù)包的流轉(zhuǎn)及處理過(guò)程增多,這也是 Nginx/HAProxy 的性能和達(dá)不到 LVS 這個(gè)量級(jí)的本質(zhì)原因。
Nginx/HAProxy 請(qǐng)求數(shù)據(jù)包走向
? ?
Nginx/HAProxy 七層的“二次連接”
相比于 Nginx/HAProxy 四層的二次連接,而 Nginx/HAProxy 七層的二次連接有些不一樣。Nginx/HAProxy 四層的二次連接,是客戶(hù)端和負(fù)載均衡進(jìn)行 TCP 三次握手后,負(fù)載均衡和后端服務(wù)器馬上進(jìn)行新的 TCP 三次握手。而 Nginx/HAProxy 七層的二次連接,在客戶(hù)端和負(fù)載均衡進(jìn)行 TCP 三次握手后,還需要等客戶(hù)端 Pushdata 傳輸數(shù)據(jù),之后負(fù)載均衡和后端服務(wù)器才會(huì)建立新的 TCP 三次握手。由此可見(jiàn),Nginx/HAProxy 四層的二次連接轉(zhuǎn)發(fā)效率會(huì)更高。加上 Nginx/HAProxy 七層會(huì)進(jìn)行一些 Rewrite 規(guī)則的判斷,會(huì)損耗一些 CPU 和內(nèi)存的性能。所以相較而言,Nginx/HAProxy 四層的性能要高許多。同樣,由于是負(fù)載均衡跟后端建立新的 TCP 三次握手及轉(zhuǎn)發(fā)客戶(hù)端請(qǐng)求的數(shù)據(jù),所以在后端服務(wù)器 netstat -n 查看到的請(qǐng)求通信的 IP 是負(fù)載均衡的 IP。所以在后端服務(wù)器中,HTTP 頭的 remote_addr 雖然代表客戶(hù)端的 IP,但實(shí)際值是負(fù)載均衡的 IP。為了避免這個(gè)情況,七層負(fù)載均衡通常會(huì)增加一個(gè)叫作 x_forwarded_for 的頭信息,把連接它的客戶(hù)端 IP(上網(wǎng)機(jī)器 IP)加到這個(gè)頭信息里,這樣就能保障后端服務(wù)器可以獲取到客戶(hù)端真實(shí)的 IP。但實(shí)際上,我們會(huì)遇到后端服務(wù)器再把請(qǐng)求轉(zhuǎn)發(fā)給到下一個(gè)目標(biāo)服務(wù)器的情況,即:“客戶(hù)端請(qǐng)求>>> Nginx >>> Nginx1 >>> Nginx2”的結(jié)構(gòu),我們?cè)?Nginx1 服務(wù)器上通過(guò) x_forwarded_for 的頭信息獲取到了客戶(hù)端的真實(shí)源 IP,那如何在 Nginx2 上進(jìn)一步獲取客戶(hù)端的源 IP 呢?在 Nginx1 上的轉(zhuǎn)發(fā)規(guī)則中,配置如下代碼:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
這樣會(huì)讓 Nginx1 轉(zhuǎn)發(fā)給后端 HTTP 頭中的 x_forwarded_for 信息中保存客戶(hù)的真實(shí)源 IP。
Nginx/HAProxy 七層三次握手?jǐn)?shù)據(jù)包走向
云訣竅?
Nginx 七層能夠進(jìn)行“二次連接”,所以通過(guò)七層 SLB,我們?cè)诤蠖朔?wù)器 ECS 中 netstat -n 查看到和后端服務(wù)器通信的 IP 為 SLB 的 IP 地址,而不能直接獲取客戶(hù)端通信的源 IP。
8
? ?
DNS 負(fù)載均衡
從 OSI 七層模型來(lái)看,DNS 的域名解析其實(shí)作用在第七層應(yīng)用層。
DNS 請(qǐng)求流向
在圖中,本質(zhì)上 DNS 的負(fù)載均衡還算不上七層負(fù)載均衡,因?yàn)?DNS 解析是在 TCP/IP 通信之前進(jìn)行的。即如果在應(yīng)用中用到了域名,需要先去請(qǐng)求 DNS 服務(wù)器獲得目標(biāo) IP 地址,才能建立 TCP/IP 通信。相較于應(yīng)用廣泛的四層和七層的負(fù)載均衡,DNS 做負(fù)載均衡的場(chǎng)景就沒(méi)那么常見(jiàn)了。DNS 做負(fù)載均衡會(huì)帶來(lái)兩個(gè)很大的問(wèn)題,兩個(gè)問(wèn)題分別如下:
實(shí)踐中,通過(guò) DNS 解析配置多個(gè) A 記錄地址。不同的客戶(hù)端來(lái)請(qǐng)求 DNS,返回 A 記錄配置的不同的源 IP(也可以是負(fù)載均衡的 VIP 地址),從而達(dá)到負(fù)載均衡的效果。但我們發(fā)現(xiàn),設(shè)置 DNS 的負(fù)載均衡,落到不同源 IP(也可以是負(fù)載均衡的 VIP 地址)的請(qǐng)求流量往往分布得很不均勻。有可能是某個(gè)后端地址的請(qǐng)求量很大,而另一個(gè)后端地址的請(qǐng)求量卻很小。
由于客戶(hù)端往往有 DNS 相應(yīng)緩存,如若 DNS 解析的某個(gè)源 IP 服務(wù)異常,一般它不會(huì)主動(dòng)剔除這個(gè)有異常的源 IP 解析。這可能會(huì)導(dǎo)致部分客戶(hù)的解析訪問(wèn)還是這個(gè)有異常的服務(wù)地址。雖然現(xiàn)在 DNS 有智能解析的高級(jí)功能,能主動(dòng)監(jiān)測(cè)后端服務(wù)的可用性。但是我們唯一不能把控的就是客戶(hù)端的 DNS 緩存,大部分客戶(hù)端的電腦 DNS 都有緩存。有可能是 DNS 已經(jīng)解析到最新的 IP,但這時(shí)候客戶(hù)端的 DNS 緩存還是會(huì)獲取解析到的舊的 IP,這會(huì)導(dǎo)致這個(gè)客戶(hù)端可能一段時(shí)間內(nèi)一直解析訪問(wèn)到那個(gè)有異常服務(wù)的 IP。
DNS 的負(fù)載均衡,一般在超大規(guī)模的應(yīng)用中,特別是跨地域的分布式應(yīng)用中運(yùn)用得非常廣泛,常規(guī)的中小型、中大型應(yīng)用,不是特別推薦嘗試 DNS 的負(fù)載均衡。DNS 作為負(fù)載均衡的應(yīng)用場(chǎng)景將會(huì)在第二篇中詳細(xì)介紹。
9
? ?
總結(jié)
不同負(fù)載均衡的類(lèi)型的功能特性匯總。
本文摘自于《阿里云運(yùn)維架構(gòu)實(shí)踐秘籍》,經(jīng)出版方授權(quán)發(fā)布。
10
? ?
福利時(shí)間
推薦語(yǔ):本書(shū)由阿里云 MVP、“喬幫主”喬銳杰所撰寫(xiě),是不可多得的運(yùn)維架構(gòu)技術(shù)實(shí)踐類(lèi)書(shū)籍,集結(jié)了作者多年一線工作實(shí)踐經(jīng)驗(yàn),也是目前市面上少有的在常見(jiàn)熱門(mén)開(kāi)源技術(shù)的基礎(chǔ)之上,結(jié)合云平臺(tái)、云產(chǎn)品,系統(tǒng)性地講解云端網(wǎng)絡(luò)、云端負(fù)載均衡、云端存儲(chǔ)、云端緩存、云端數(shù)據(jù)庫(kù)、云端運(yùn)維、云端監(jiān)控、云端容器、云端自動(dòng)化運(yùn)維/云端 DevOps、云端安全、云端架構(gòu)等技術(shù)的實(shí)踐圖書(shū)。書(shū)中總結(jié)及歸納了將近三十種實(shí)踐的云秘訣,為讀者在風(fēng)起“云”涌的時(shí)代,提供過(guò)關(guān)斬將的“尚方寶劍”。
中生代技術(shù)聯(lián)合機(jī)械工業(yè)華章圖書(shū)給大家?guī)?lái)福利。
《阿里云運(yùn)維架構(gòu)實(shí)踐秘籍》
推薦語(yǔ):
送書(shū)規(guī)則:截止2020年5月15日13:30前在留言區(qū),分享你在云技術(shù)方面的心得與踩坑經(jīng)驗(yàn)、或者對(duì)新技術(shù)的更新、迭代有何獨(dú)特的個(gè)人見(jiàn)解,精選留言點(diǎn)贊1-5名各送出此書(shū)一本。
注:獲得贈(zèng)書(shū)資格的讀者須于8小時(shí)內(nèi)聯(lián)系小編發(fā)送詳細(xì)收貨信息,逾期則視為主動(dòng)放棄。
想要加入中生代架構(gòu)群的小伙伴,請(qǐng)?zhí)砑尤汉匣锶?strong>大白的微信
申請(qǐng)備注(姓名+公司+技術(shù)方向)才能通過(guò)哦!
? ?END ? ?? #接力技術(shù),鏈接價(jià)值#精彩推薦1.?GitHub在線開(kāi)發(fā)工具上線,是時(shí)候卸載IDE了2.?阿里高級(jí)技術(shù)專(zhuān)家邱小俠:微服務(wù)架構(gòu)的理論基礎(chǔ) - 康威定律 3.?導(dǎo)致微服務(wù)失敗的 11 個(gè)原因 4.?Facebook和Google應(yīng)該向新聞媒體付費(fèi)?漫畫(huà)推薦1.?漫畫(huà):程序員和產(chǎn)品經(jīng)理撕得真是太太太太厲害了 2.?漫畫(huà):程序員真的是太太太太太太太太難了!3.?漫畫(huà):普通程序員 vs 優(yōu)秀程序員 4.?漫畫(huà):35歲的IT何去何從? 5.?漫畫(huà):從修燈泡來(lái)看各種 IT 崗位,你是哪一種? 6. 漫畫(huà):一批90后已經(jīng)30歲了,更扎心的是…7. 圖解:這才是程序員加班的真正原因!8.?漫畫(huà):中國(guó)互聯(lián)網(wǎng)往事(2000-2020)好文點(diǎn)個(gè)在看吧!點(diǎn)擊閱讀原文可以薅當(dāng)當(dāng)羊毛哦
總結(jié)
以上是生活随笔為你收集整理的阿里云MVP乔帮主:五大类型负载均衡的原理场景详解(文末赠书)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 因为一次宕机,终于搞透了 Kafka 高
- 下一篇: hdu-4704 sum(费马小定理)