1.什么是負(fù)載均衡?
當(dāng)一臺(tái)服務(wù)器的性能達(dá)到極限時(shí),我們可以使用服務(wù)器集群來提高網(wǎng)站的整體性能扼雏。那么,在服務(wù)器集群中夯膀,需要有一臺(tái)服務(wù)器充當(dāng)調(diào)度者的角色呢蛤,用戶的所有請(qǐng)求都會(huì)首先由它接收,調(diào)度者再根據(jù)每臺(tái)服務(wù)器的負(fù)載情況將請(qǐng)求分配給某一臺(tái)后端服務(wù)器去處理棍郎。
那么在這個(gè)過程中其障,調(diào)度者如何合理分配任務(wù),保證所有后端服務(wù)器都將性能充分發(fā)揮涂佃,從而保持服務(wù)器集群的整體性能最優(yōu)励翼,這就是負(fù)載均衡問題。
下面詳細(xì)介紹負(fù)載均衡的四種實(shí)現(xiàn)方式辜荠。
(一)HTTP重定向?qū)崿F(xiàn)負(fù)載均衡
過程描述
當(dāng)用戶向服務(wù)器發(fā)起請(qǐng)求時(shí)汽抚,請(qǐng)求首先被集群調(diào)度者截獲;調(diào)度者根據(jù)某種分配策略伯病,選擇一臺(tái)服務(wù)器造烁,并將選中的服務(wù)器的IP地址封裝在HTTP響應(yīng)消息頭部的Location字段中,并將響應(yīng)消息的狀態(tài)碼設(shè)為302午笛,最后將這個(gè)響應(yīng)消息返回給瀏覽器惭蟋。
當(dāng)瀏覽器收到響應(yīng)消息后,解析Location字段药磺,并向該URL發(fā)起請(qǐng)求告组,然后指定的服務(wù)器處理該用戶的請(qǐng)求,最后將結(jié)果返回給用戶癌佩。
在使用HTTP重定向來實(shí)現(xiàn)服務(wù)器集群負(fù)載均衡的過程中木缝,需要一臺(tái)服務(wù)器作為請(qǐng)求調(diào)度者。用戶的一項(xiàng)操作需要發(fā)起兩次HTTP請(qǐng)求围辙,一次向調(diào)度服務(wù)器發(fā)送請(qǐng)求我碟,獲取后端服務(wù)器的IP,第二次向后端服務(wù)器發(fā)送請(qǐng)求姚建,獲取處理結(jié)果矫俺。
調(diào)度策略
調(diào)度服務(wù)器收到用戶的請(qǐng)求后,究竟選擇哪臺(tái)后端服務(wù)器處理請(qǐng)求,這由調(diào)度服務(wù)器所使用的調(diào)度策略決定恳守。
1.隨機(jī)分配策略 當(dāng)調(diào)度服務(wù)器收到用戶請(qǐng)求后考婴,可以隨機(jī)決定使用哪臺(tái)后端服務(wù)器,然后將該服務(wù)器的IP封裝在HTTP響應(yīng)消息的Location屬性中催烘,返回給瀏覽器即可沥阱。
2.輪詢策略(RR) 調(diào)度服務(wù)器需要維護(hù)一個(gè)值,用于記錄上次分配的后端服務(wù)器的IP伊群。那么當(dāng)新的請(qǐng)求到來時(shí)考杉,調(diào)度者將請(qǐng)求依次分配給下一臺(tái)服務(wù)器。
由于輪詢策略需要調(diào)度者維護(hù)一個(gè)值用于記錄上次分配的服務(wù)器IP舰始,因此需要額外的開銷崇棠;此外,由于這個(gè)值屬于互斥資源丸卷,那么當(dāng)多個(gè)請(qǐng)求同時(shí)到來時(shí)枕稀,為了避免線程的安全問題,因此需要鎖定互斥資源谜嫉,從而降低了性能萎坷。而隨機(jī)分配策略不需要維護(hù)額外的值,也就不存在線程安全問題沐兰,因此性能比輪詢要高哆档。
優(yōu)缺點(diǎn)分析
采用HTTP重定向來實(shí)現(xiàn)服務(wù)器集群的負(fù)載均衡實(shí)現(xiàn)起來較為容易,邏輯比較簡(jiǎn)單住闯,但缺點(diǎn)也較為明顯瓜浸。
在HTTP重定向方法中,調(diào)度服務(wù)器只在客戶端第一次向網(wǎng)站發(fā)起請(qǐng)求的時(shí)候起作用比原。當(dāng)調(diào)度服務(wù)器向?yàn)g覽器返回響應(yīng)信息后插佛,客戶端此后的操作都基于新的URL進(jìn)行的(也就是后端服務(wù)器),此后瀏覽器就不會(huì)與調(diào)度服務(wù)器產(chǎn)生關(guān)系春寿,進(jìn)而會(huì)產(chǎn)生如下幾個(gè)問題:
由于不同用戶的訪問時(shí)間朗涩、訪問頁面深度有所不同,從而每個(gè)用戶對(duì)各自的后端服務(wù)器所造成的壓力也不同绑改。而調(diào)度服務(wù)器在調(diào)度時(shí),無法知道當(dāng)前用戶將會(huì)對(duì)服務(wù)器造成多大的壓力兄一,因此這種方式無法實(shí)現(xiàn)真正意義上的負(fù)載均衡厘线,只不過是把請(qǐng)求次數(shù)平均分配給每臺(tái)服務(wù)器罷了。若分配給該用戶的后端服務(wù)器出現(xiàn)故障出革,并且如果頁面被瀏覽器緩存造壮,那么當(dāng)用戶再次訪問網(wǎng)站時(shí),請(qǐng)求都會(huì)發(fā)給出現(xiàn)故障的服務(wù)器,從而導(dǎo)致訪問失敗耳璧。
(二)DNS負(fù)載均衡
DNS是什么成箫?
在了解DNS負(fù)載均衡之前,我們首先需要了解DNS域名解析的過程旨枯。
我們知道蹬昌,數(shù)據(jù)包采用IP地址在網(wǎng)絡(luò)中傳播,而為了方便用戶記憶攀隔,我們使用域名來訪問網(wǎng)站皂贩。那么,我們通過域名訪問網(wǎng)站之前昆汹,首先需要將域名解析成IP地址明刷,這個(gè)工作是由DNS完成的。也就是域名服務(wù)器满粗。
我們提交的請(qǐng)求不會(huì)直接發(fā)送給想要訪問的網(wǎng)站辈末,而是首先發(fā)給域名服務(wù)器,它會(huì)幫我們把域名解析成IP地址并返回給我們映皆。我們收到IP之后才會(huì)向該IP發(fā)起請(qǐng)求挤聘。
那么,DNS服務(wù)器有一個(gè)天然的優(yōu)勢(shì)劫扒,如果一個(gè)域名指向了多個(gè)IP地址檬洞,那么每次進(jìn)行域名解析時(shí),DNS只要選一個(gè)IP返回給用戶沟饥,就能夠?qū)崿F(xiàn)服務(wù)器集群的負(fù)載均衡添怔。
具體做法
首先需要將我們的域名指向多個(gè)后端服務(wù)器(將一個(gè)域名解析到多個(gè)IP上),再設(shè)置一下調(diào)度策略贤旷,那么我們的準(zhǔn)備工作就完成了广料,接下來的負(fù)載均衡就完全由DNS服務(wù)器來實(shí)現(xiàn)。
當(dāng)用戶向我們的域名發(fā)起請(qǐng)求時(shí)幼驶,DNS服務(wù)器會(huì)自動(dòng)地根據(jù)我們事先設(shè)定好的調(diào)度策略選一個(gè)合適的IP返回給用戶艾杏,用戶再向該IP發(fā)起請(qǐng)求。
調(diào)度策略
一般DNS提供商會(huì)提供一些調(diào)度策略供我們選擇盅藻,如隨機(jī)分配购桑、輪詢、根據(jù)請(qǐng)求者的地域分配離他最近的服務(wù)器氏淑。
優(yōu)缺點(diǎn)分析
DNS負(fù)載均衡最大的優(yōu)點(diǎn)就是配置簡(jiǎn)單勃蜘。服務(wù)器集群的調(diào)度工作完全由DNS服務(wù)器承擔(dān),那么我們就可以把精力放在后端服務(wù)器上假残,保證他們的穩(wěn)定性與吞吐量缭贡。而且完全不用擔(dān)心DNS服務(wù)器的性能,即便是使用了輪詢策略,它的吞吐率依然卓越阳惹。
此外谍失,DNS負(fù)載均衡具有較強(qiáng)了擴(kuò)展性,你完全可以為一個(gè)域名解析較多的IP莹汤,而且不用擔(dān)心性能問題快鱼。
但是,由于把集群調(diào)度權(quán)交給了DNS服務(wù)器体啰,從而我們沒辦法隨心所欲地控制調(diào)度者攒巍,沒辦法定制調(diào)度策略。
DNS服務(wù)器也沒辦法了解每臺(tái)服務(wù)器的負(fù)載情況荒勇,因此沒辦法實(shí)現(xiàn)真正意義上的負(fù)載均衡柒莉。它和HTTP重定向一樣,只不過把所有請(qǐng)求平均分配給后端服務(wù)器罷了沽翔。
此外兢孝,當(dāng)我們發(fā)現(xiàn)某一臺(tái)后端服務(wù)器發(fā)生故障時(shí),即使我們立即將該服務(wù)器從域名解析中去除仅偎,但由于DNS服務(wù)器會(huì)有緩存跨蟹,該IP仍然會(huì)在DNS中保留一段時(shí)間,那么就會(huì)導(dǎo)致一部分用戶無法正常訪問網(wǎng)站橘沥。這是一個(gè)致命的問題窗轩!好在這個(gè)問題可以用動(dòng)態(tài)DNS來解決。
動(dòng)態(tài)DNS
動(dòng)態(tài)DNS能夠讓我們通過程序動(dòng)態(tài)修改DNS服務(wù)器中的域名解析座咆。從而當(dāng)我們的監(jiān)控程序發(fā)現(xiàn)某臺(tái)服務(wù)器掛了之后痢艺,能立即通知DNS將其刪掉。
綜上所述
DNS負(fù)載均衡是一種粗獷的負(fù)載均衡方法介陶,這里只做介紹堤舒,不推薦使用。
(三)反向代理負(fù)載均衡
1.什么是反向代理負(fù)載均衡哺呜?
反向代理服務(wù)器是一個(gè)位于實(shí)際服務(wù)器之前的服務(wù)器舌缤,所有向我們網(wǎng)站發(fā)來的請(qǐng)求都首先要經(jīng)過反向代理服務(wù)器,服務(wù)器根據(jù)用戶的請(qǐng)求要么直接將結(jié)果返回給用戶某残,要么將請(qǐng)求交給后端服務(wù)器處理国撵,再返回給用戶。
之前我們介紹了用反向代理服務(wù)器實(shí)現(xiàn)靜態(tài)頁面和常用的動(dòng)態(tài)頁面的緩存玻墅。接下來我們介紹反向代理服務(wù)器更常用的功能——實(shí)現(xiàn)負(fù)載均衡卸留。
我們知道,所有發(fā)送給我們網(wǎng)站的請(qǐng)求都首先經(jīng)過反向代理服務(wù)器椭豫。那么,反向代理服務(wù)器就可以充當(dāng)服務(wù)器集群的調(diào)度者,它可以根據(jù)當(dāng)前后端服務(wù)器的負(fù)載情況赏酥,將請(qǐng)求轉(zhuǎn)發(fā)給一臺(tái)合適的服務(wù)器喳整,并將處理結(jié)果返回給用戶。
優(yōu)點(diǎn)
1.隱藏后端服務(wù)器裸扶。與HTTP重定向相比框都,反向代理能夠隱藏后端服務(wù)器,所有瀏覽器都不會(huì)與后端服務(wù)器直接交互呵晨,從而能夠確保調(diào)度者的控制權(quán)魏保,提升集群的整體性能。
2.故障轉(zhuǎn)移摸屠。與DNS負(fù)載均衡相比谓罗,反向代理能夠更快速地移除故障結(jié)點(diǎn)。當(dāng)監(jiān)控程序發(fā)現(xiàn)某一后端服務(wù)器出現(xiàn)故障時(shí)季二,能夠及時(shí)通知反向代理服務(wù)器檩咱,并立即將其刪除。
3.合理分配任務(wù) HTTP重定向和DNS負(fù)載均衡都無法實(shí)現(xiàn)真正意義上的負(fù)載均衡胯舷,也就是調(diào)度服務(wù)器無法根據(jù)后端服務(wù)器的實(shí)際負(fù)載情況分配任務(wù)刻蚯。但反向代理服務(wù)器支持手動(dòng)設(shè)定每臺(tái)后端服務(wù)器的權(quán)重。我們可以根據(jù)服務(wù)器的配置設(shè)置不同的權(quán)重桑嘶,權(quán)重的不同會(huì)導(dǎo)致被調(diào)度者選中的概率的不同炊汹。
缺點(diǎn)
1.調(diào)度者壓力過大由于所有的請(qǐng)求都先由反向代理服務(wù)器處理,那么當(dāng)請(qǐng)求量超過調(diào)度服務(wù)器的最大負(fù)載時(shí)逃顶,調(diào)度服務(wù)器的吞吐率降低會(huì)直接降低集群的整體性能讨便。
2.制約擴(kuò)展 當(dāng)后端服務(wù)器也無法滿足巨大的吞吐量時(shí),就需要增加后端服務(wù)器的數(shù)量口蝠,可沒辦法無限量地增加器钟,因?yàn)闀?huì)受到調(diào)度服務(wù)器的最大吞吐量的制約。
粘滯會(huì)話
反向代理服務(wù)器會(huì)引起一個(gè)問題妙蔗。若某臺(tái)后端服務(wù)器處理了用戶的請(qǐng)求傲霸,并保存了該用戶的session或存儲(chǔ)了緩存,那么當(dāng)該用戶再次發(fā)送請(qǐng)求時(shí)眉反,無法保證該請(qǐng)求仍然由保存了其Session或緩存的服務(wù)器處理昙啄,若由其他服務(wù)器處理,先前的Session或緩存就找不到了寸五。
解決辦法1: 可以修改反向代理服務(wù)器的任務(wù)分配策略梳凛,以用戶IP作為標(biāo)識(shí)較為合適。相同的用戶IP會(huì)交由同一臺(tái)后端服務(wù)器處理梳杏,從而就避免了粘滯會(huì)話的問題韧拒。
解決辦法2:可以在Cookie中標(biāo)注請(qǐng)求的服務(wù)器ID淹接,當(dāng)再次提交請(qǐng)求時(shí),調(diào)度者將該請(qǐng)求分配給Cookie中標(biāo)注的服務(wù)器處理即可叛溢。
2.負(fù)載均衡組件
apache
—— 它是Apache軟件基金會(huì)的一個(gè)開放源代碼的跨平臺(tái)的網(wǎng)頁服務(wù)器塑悼,屬于老牌的web服務(wù)器了,支持基于Ip或者域名的虛擬主機(jī)楷掉,支持代理服務(wù)器厢蒜,支持安全Socket層(SSL)等等,目前互聯(lián)網(wǎng)主要使用它做靜態(tài)資源服務(wù)器烹植,也可以做代理服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求(如:圖片鏈等)斑鸦,結(jié)合tomcat等servlet容器處理jsp。
ngnix
—— 俄羅斯人開發(fā)的一個(gè)高性能的 HTTP和反向代理服務(wù)器草雕。由于Nginx 超越 Apache 的高性能和穩(wěn)定性巷屿,使得國內(nèi)使用 Nginx 作為 Web 服務(wù)器的網(wǎng)站也越來越多,其中包括新浪博客促绵、新浪播客攒庵、網(wǎng)易新聞、騰訊網(wǎng)败晴、搜狐博客等門戶網(wǎng)站頻道等浓冒,在3w以上的高并發(fā)環(huán)境下,ngnix處理能力相當(dāng)于apache的10倍尖坤。 參考:apache和tomcat的性能分析和對(duì)比(http://blog.s135.com/nginx_php_v6/)
lvs
—— Linux Virtual Server的簡(jiǎn)寫稳懒,意即Linux虛擬服務(wù)器,是一個(gè)虛擬的服務(wù)器集群系統(tǒng)慢味。由畢業(yè)于國防科技大學(xué)的章文嵩博士于1998年5月創(chuàng)立场梆,可以實(shí)現(xiàn)LINUX平臺(tái)下的簡(jiǎn)單負(fù)載均衡。了解更多纯路,訪問官網(wǎng):http://zh.linuxvirtualserver.org/或油。
HAProxy
—— HAProxy提供高可用性、負(fù)載均衡以及基于TCP和HTTP應(yīng)用的代理驰唬,支持虛擬主機(jī)顶岸,它是免費(fèi)、快速并且可靠的一種解決方案叫编。HAProxy特別適用于那些負(fù)載特大的web站點(diǎn)辖佣, 這些站點(diǎn)通常又需要會(huì)話保持或七層處理。HAProxy運(yùn)行在當(dāng)前的硬件上搓逾,完全可以支持?jǐn)?shù)以萬計(jì)的并發(fā)連接卷谈。并且它的運(yùn)行模式使得它可以很簡(jiǎn)單安全的整合進(jìn)您當(dāng)前的架構(gòu)中, 同時(shí)可以保護(hù)你的web服務(wù)器不被暴露到網(wǎng)絡(luò)上.
keepalived
—— 這里說的keepalived不是apache或者tomcat等某個(gè)組件上的屬性字段霞篡,它也是一個(gè)組件世蔗,可以實(shí)現(xiàn)web服務(wù)器的高可用(HA high availably)端逼。它可以檢測(cè)web服務(wù)器的工作狀態(tài),如果該服務(wù)器出現(xiàn)故障被檢測(cè)到凸郑,將其剔除服務(wù)器群中裳食,直至正常工作后,keepalive會(huì)自動(dòng)檢測(cè)到并加入到服務(wù)器群里面芙沥。實(shí)現(xiàn)主備服務(wù)器發(fā)生故障時(shí)ip瞬時(shí)無縫交接。它是LVS集群節(jié)點(diǎn)健康檢測(cè)的一個(gè)用戶空間守護(hù)進(jìn)程浊吏,也是LVS的引導(dǎo)故障轉(zhuǎn)移模塊(director failover)而昨。Keepalived守護(hù)進(jìn)程可以檢查L(zhǎng)VS池的狀態(tài)。如果LVS服務(wù)器池當(dāng)中的某一個(gè)服務(wù)器宕機(jī)了找田。keepalived會(huì)通過一 個(gè)setsockopt呼叫通知內(nèi)核將這個(gè)節(jié)點(diǎn)從LVS拓?fù)鋱D中移除歌憨。
memcached
—— 它是一個(gè)高性能分布式內(nèi)存對(duì)象緩存系統(tǒng)。當(dāng)初是Danga Interactive為了LiveJournal快速發(fā)展開發(fā)的系統(tǒng)墩衙,用于對(duì)業(yè)務(wù)查詢數(shù)據(jù)緩存务嫡,減輕數(shù)據(jù)庫的負(fù)載。其守護(hù)進(jìn)程(daemon)是用C寫的漆改,但是客戶端支持幾乎所有語言(客戶端基本上有3種版本[memcache client for java;spymemcached;xMecache])心铃,服務(wù)端和客戶端通過簡(jiǎn)單的協(xié)議通信;在memcached里面緩存的數(shù)據(jù)必須序列化挫剑。
歡迎工作一到五年的Java工程師朋友們加入Java高并發(fā): 957734884去扣,群內(nèi)提供免費(fèi)的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)樊破、高性能及分布式愉棱、Jvm性能調(diào)優(yōu)、Spring源碼哲戚,MyBatis奔滑,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)合理利用自己每一分每一秒的時(shí)間來學(xué)習(xí)提升自己,不要再用"沒有時(shí)間“來掩飾自己思想上的懶惰顺少!趁年輕朋其,使勁拼,給未來的自己一個(gè)交代祈纯!
terracotta
—— 是一款由美國Terracotta公司開發(fā)的著名開源Java集群平臺(tái)令宿。它在JVM與Java應(yīng)用之間實(shí)現(xiàn)了一個(gè)專門處理集群功能的抽象層,允許用戶在不改變系統(tǒng)代碼的情況下實(shí)現(xiàn)java應(yīng)用的集群腕窥。支持?jǐn)?shù)據(jù)的持久化粒没、session的復(fù)制以及高可用(HA)。